C117 莫队配合 bitset P4688 [Ynoi2016] 掉进兔子洞
视频链接:C117 莫队配合 bitset P4688 [Ynoi2016] 掉进兔子洞_哔哩哔哩_bilibili
// 莫队配合 bitset O(n*sqrt(n)) #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <bitset> using namespace std; const int N=100005,M=N/3; int n,m,B,a[N],b[N],p[N],sum[M]; bitset<N> bs[M],now; struct Q{ int l,r,id; bool operator<(const Q& x) const{ if(l/B!=x.l/B) return l<x.l; return (l/B)&1 ? r<x.r : r>x.r; } }q[N]; void add(int x){ now.set(x+p[x]); //x位置 置1 p[x]++; //相同数的位置偏移量 } void del(int x){ p[x]--; now.reset(x+p[x]); //x位置 置0 } void solve(){ memset(p,0,sizeof(p)); int cnt=0,tot=0; //cnt查询数,tot区间数 now.reset(); //全置0 for(cnt=0;cnt<M&&m;m--,cnt++){ //查询 sum[cnt]=0; bs[cnt].set(); //全置1 for(int j=0;j<3;j++){ scanf("%d%d",&q[tot].l,&q[tot].r); q[tot].id=cnt; sum[cnt]+=q[tot].r-q[tot].l+1; tot++; } } sort(q,q+tot); //区间排序 for(int i=0,l=1,r=0;i<tot;i++){ //莫队 while(l>q[i].l) add(a[--l]); while(r<q[i].r) add(a[++r]); while(l<q[i].l) del(a[l++]); while(r>q[i].r) del(a[r--]); bs[q[i].id]&=now; //查询的交集 } for(int i=0;i<cnt;i++) //查询 printf("%d\n",sum[i]-bs[i].count()*3); } int main(){ scanf("%d%d",&n,&m); B=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i]; sort(b+1,b+n+1); for(int i=1;i<=n;i++) //不去重的离散化 a[i]=lower_bound(b+1,b+n+1,a[i])-b; solve();solve();solve(); //分三段处理 }
P3674 小清新人渣的本愿 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P5355 [Ynoi2017] 由乃的玉米田 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P5313 [Ynoi2011] WBLT - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)