C117 莫队配合 bitset P4688 [Ynoi2016] 掉进兔子洞

视频链接:C117 莫队配合 bitset P4688 [Ynoi2016] 掉进兔子洞_哔哩哔哩_bilibili

 

 

 

Luogu P4688 [Ynoi2016] 掉进兔子洞

// 莫队配合 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)

 

posted @ 2024-04-19 21:57  董晓  阅读(205)  评论(0编辑  收藏  举报