这算法的名字应该是
[The Method of Four Russians
]
引入:[LOJ6499] 颜色
求一坨区间内出现的颜色个数
(n,Tle 10^5),(Memory Limits =8 Mib)
比较简单的做法是分块完了 (bitset)
然后我们发现这个 (bitset) 是没法做的
每个询问中间的部分与答案的部分复杂度很高
那么可以考虑用 (st) 表或者线段树优化这个过程
这题目直接 (ST) 表加上手写 (Bitset) 就冲过去了
收获:如何手写 (bitset),(st) 表优化分块的思路
#include<bits/stdc++.h>
using namespace std;
#define reg register
namespace yspm{
inline int read(){
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=1e5+10,P=(N>>5)+10,SZ=(1<<16)+1;
int b[N],c,a[N],n,T,p,bl[N],block,ct[SZ];
struct BITSET{
unsigned int a[P];
BITSET operator |(BITSET tp) const{
BITSET res;
for(reg int i=0;i<=c;++i) res.a[i]=a[i]|tp.a[i];
return res;
}
inline void clear(){
for(reg int i=0;i<=c;++i) a[i]=0;
return ;
}
inline void set(int x){
a[x>>5]|=1u<<(x&31);
return ;
}
inline int count(){
int res=0;
for(reg int i=0;i<=c;++i){
res+=ct[a[i]>>16]+ct[a[i]&65535];
}return res;
}
}ans,f[80][9];
inline void work(int l,int r){
if(bl[l]+1>=bl[r]){
for(reg int i=l;i<=r;++i) ans.set(a[i]);
}else{
for(reg int i=l;bl[i]==bl[l];++i) ans.set(a[i]);
for(reg int i=r;bl[i]==bl[r];--i) ans.set(a[i]);
int t=log2(bl[r]-bl[l]-1);
ans=ans|f[bl[l]+1][t]|f[bl[r]-(1<<t)][t];
} return ;
}
int lans;
signed main(){
n=read(); T=read(); p=read(); block=sqrt(1.2*log2(n+1)*n);
for(reg int i=1;i<=65535;++i){
for(reg int T=i;T;T=(T-1)&T) ++ct[i];
}
for(reg int i=1;i<=n;++i) bl[i]=i/block+1,b[i]=a[i]=read();
sort(b+1,b+n+1); c=unique(b+1,b+n+1)-b-1;
for(reg int i=1;i<=n;++i) {
a[i]=lower_bound(b+1,b+c+1,a[i])-b;
f[bl[i]][0].set(a[i]);
}
c>>=5;
for(reg int j=1;(1<<j)<=bl[n];++j){
for(reg int i=1;i+(1<<j)-1<=bl[n];++i){
f[i][j]=f[i][j-1]|f[i+(1<<(j-1))][j-1];
}
}
bool fl=0;
while(T--){
ans.clear();
int k=read();
while(k--){
int l=read(),r=read();
if(p&&fl){
l=(l^lans)%n+1,r=(r^lans)%n+1;
} if(r<l) swap(l,r);
work(l,r);
}fl=1;
printf("%d
",lans=ans.count());
}
return 0;
}
}
signed main(){
return yspm::main();
}
不过这代码里面块的大小是嫖的……
具体怎么算留坑了
然后是下一个题目
https://ac.nowcoder.com/acm/contest/8282/F
答案容斥完了就是所有颜色剪掉 (dfn) 序不在那个区间里面的情况
所以四毛子上去即可
但是卡空间,那么把询问分成 (10) 组再做就行了
[sto skyh orz
]
代码还没写