莫队+分块。。分块修改O(1),查询O(n^0.5)
总复杂度O(n^1.5)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define ll long long 7 using namespace std; 8 const int maxn=100233; 9 struct zs{int l,r,a,b,id;}q[1002333]; 10 int B[maxn],a[maxn],mp[maxn],l[maxn],r[maxn]; 11 int ans[1002333]; 12 int sz[2333]; 13 int i,j,k,n,m,kuai; 14 15 int ra;char rx; 16 inline int read(){ 17 rx=getchar(),ra=0; 18 while(rx<'0'||rx>'9')rx=getchar(); 19 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 20 } 21 22 inline void add(int x){sz[B[x]]+=!mp[x],mp[x]++;} 23 inline void del(int x){mp[x]--,sz[B[x]]-=!mp[x];} 24 inline int query(int a,int b){ 25 register int i;int sm=0,idl=B[a],idr=B[b]; 26 if(idl==idr){ 27 for(i=a;i<=b;i++)sm+=mp[i]>0; 28 return sm; 29 } 30 for(i=a;i<=r[idl];i++)sm+=mp[i]>0; 31 for(i=l[idr];i<=b;i++)sm+=mp[i]>0; 32 for(i=idl+1;i<idr;i++)sm+=sz[i]; 33 return sm; 34 } 35 36 bool cmp(zs a,zs b){return B[a.l]==B[b.l]?((B[a.l]&1)?a.r<b.r:a.r>b.r):B[a.l]<B[b.l];} 37 int main(){ 38 n=read(),m=read();kuai=(int)sqrt(n)+3; 39 for(i=1;i<=n;i++)a[i]=read(),B[i]=(i+kuai-1)/kuai; 40 for(i=1;i<=B[n];i++) 41 l[i]=(i-1)*kuai+1,r[i]=i==B[n]?n:(l[i]+kuai-1); 42 for(i=1;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].a=read(),q[i].b=read(),q[i].id=i; 43 sort(q+1,q+1+m,cmp); 44 register int l=1,r=0; 45 for(i=1;i<=m;i++){ 46 while(l>q[i].l)l--,add(a[l]); 47 while(r<q[i].r)r++,add(a[r]); 48 while(l<q[i].l)del(a[l]),l++; 49 while(r>q[i].r)del(a[r]),r--; 50 ans[q[i].id]=query(q[i].a,q[i].b); 51 } 52 for(i=1;i<=m;i++)printf("%d ",ans[i]); 53 return 0; 54 }