emmm......我把莫队扔到了杂题里,因为感觉局限挺大的=。=
这题是莫队维护信息+分块查询答案,都是两者的基本操作,复杂度$O(m$ $sqrt(n)+n$ $sqrt(m))$
所以为啥要写这水题的题解来着
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=100005,Sq=320; 7 struct a 8 { 9 long long ans,num; 10 int l,r,xx,yy,v,id; 11 }mo[N]; 12 int b[N],blo[N],cnt[N],exi[Sq],bkt[Sq],pts[Sq][2]; 13 int n,m,t1,t2,t3,t4,lp,rp,sqr,srt,xnt,maxx; 14 bool cmp(a x,a y) 15 { 16 return x.v==y.v?x.r<y.r:x.v<y.v; 17 } 18 bool com(a x,a y) 19 { 20 return x.id<y.id; 21 } 22 void change(int val,int typ) 23 { 24 if(typ) 25 { 26 bkt[blo[val]]++; 27 exi[blo[val]]+=(++cnt[val]==1); 28 } 29 else 30 { 31 bkt[blo[val]]--; 32 exi[blo[val]]-=(!(--cnt[val])); 33 } 34 } 35 int query1(int x,int y) 36 { 37 int ret=0; 38 if(blo[x]!=blo[y]) 39 { 40 for(int i=x;i<=pts[blo[x]][1];i++) ret+=cnt[i]; 41 for(int i=pts[blo[y]][0];i<=y;i++) ret+=cnt[i]; 42 for(int i=blo[x]+1;i<=blo[y]-1;i++) ret+=bkt[i]; 43 } 44 else for(int i=x;i<=y;i++) ret+=cnt[i]; 45 return ret; 46 } 47 int query2(int x,int y) 48 { 49 int ret=0; 50 if(blo[x]!=blo[y]) 51 { 52 for(int i=x;i<=pts[blo[x]][1];i++) ret+=(cnt[i]>0); 53 for(int i=pts[blo[y]][0];i<=y;i++) ret+=(cnt[i]>0); 54 for(int i=blo[x]+1;i<=blo[y]-1;i++) ret+=exi[i]; 55 } 56 else for(int i=x;i<=y;i++) ret+=(cnt[i]>0); 57 return ret; 58 } 59 int main () 60 { 61 scanf("%d%d",&n,&m),sqr=sqrt(n); 62 for(int i=1;i<=n;i++) 63 scanf("%d",&b[i]),maxx=max(maxx,b[i]); 64 for(int i=1;i<=m;i++) 65 { 66 scanf("%d%d%d%d",&t1,&t2,&t3,&t4); 67 mo[i].v=(t1-1)/sqr+1,mo[i].id=i,maxx=max(maxx,t4); 68 mo[i].l=t1,mo[i].r=t2,mo[i].xx=t3,mo[i].yy=t4; 69 } 70 pts[xnt=1][0]=1,srt=sqrt(maxx); 71 for(int i=1;i<=n;i++) 72 { 73 blo[i]=(i-1)/srt+1; 74 if(i%srt==0) 75 { 76 pts[xnt++][1]=i; 77 pts[xnt][0]=i+1; 78 } 79 } 80 pts[xnt][1]=maxx,lp=1; 81 sort(mo+1,mo+1+m,cmp); 82 for(int i=1;i<=m;i++) 83 { 84 while(lp<mo[i].l) change(b[lp++],0); 85 while(lp>mo[i].l) change(b[--lp],1); 86 while(rp<mo[i].r) change(b[++rp],1); 87 while(rp>mo[i].r) change(b[rp--],0); 88 mo[i].ans=query1(mo[i].xx,mo[i].yy); 89 mo[i].num=query2(mo[i].xx,mo[i].yy); 90 } 91 sort(mo+1,mo+1+m,com); 92 for(int i=1;i<=m;i++) 93 printf("%lld %lld ",mo[i].ans,mo[i].num); 94 return 0; 95 }