题解:P15586 [KTSC 2026] 五万酱汁 / 50,000 Sauces
观察题目所给要求:每次询问集合的大小大约为总大小的一半。先考虑
拓展到
讲一下容斥细节。
对于六个部分
三个部分交叉的答案用三个部分的询问减两个部分的再减一个部分的即可。不再赘述,可以自行画图理解,详见代码。
#include<vector>
using std::vector;
int query(std::vector<int>);
using namespace std;
int solve(int n){
vector<int> a[6];
int ans=0,cnt1[6]={0},cnt2[36]={0};
for(int i=0;i<n;i++){
a[i%6].push_back(i);
}
for(int i=0;i<6;i++){
ans+=cnt1[i]=query(a[i]);
}
for(int i=0;i<6;i++){
for(int j=i+1;j<6;j++){
vector<int> v;
for(int x:a[i]) v.push_back(x);
for(int x:a[j]) v.push_back(x);
ans+=cnt2[i*6+j]=query(v)-cnt1[i]-cnt1[j];
}
}
for(int i=0;i<6;i++){
for(int j=i+1;j<6;j++){
for(int k=j+1;k<6;k++){
vector<int> v;
for(int x:a[i]) v.push_back(x);
for(int x:a[j]) v.push_back(x);
for(int x:a[k]) v.push_back(x);
ans+=query(v)-cnt2[i*6+j]-cnt2[i*6+k]-cnt2[j*6+k]-cnt1[i]-cnt1[j]-cnt1[k];
}
}
}
return ans;
}