Bzoj 3236: [Ahoi2013]作业 莫队,分块
3236: [Ahoi2013]作业
Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1113 Solved: 428
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
Sample Output
2 2
1 1
3 2
2 1
1 1
3 2
2 1
HINT
N=100000,M=1000000
Source
题解:
莫队+分块乱搞。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define MAXN 100010 4 #define MAXM 1000010 5 int block,sum[MAXN],tot[MAXN],num[351],color[MAXN],pos[MAXN],ans1[MAXM],ans2[MAXM]; 6 struct node 7 { 8 int l,r,a,b,id; 9 }q[MAXM]; 10 int read() 11 { 12 int s=0,fh=1;char ch=getchar(); 13 while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();} 14 while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();} 15 return s*fh; 16 } 17 bool cmp(node aa,node bb) 18 { 19 if(pos[aa.l]==pos[bb.l])return aa.r<bb.r; 20 return aa.l<bb.l; 21 } 22 void Del(int C) 23 { 24 int cc=pos[C]; 25 sum[cc]--;tot[C]--; 26 if(tot[C]==0)num[cc]--; 27 } 28 void Add(int C) 29 { 30 int cc=pos[C]; 31 sum[cc]++;tot[C]++; 32 if(tot[C]==1)num[cc]++; 33 } 34 int getans1(int aa,int bb) 35 { 36 int p1=pos[aa],p2=pos[bb],gs=0,i; 37 if(p1==p2) 38 { 39 for(i=aa;i<=bb;i++)gs+=tot[i]; 40 return gs; 41 } 42 for(i=aa;i<=p1*block;i++)gs+=tot[i]; 43 for(i=p1+1;i<=p2-1;i++)gs+=sum[i]; 44 for(i=(p2-1)*block+1;i<=bb;i++)gs+=tot[i]; 45 return gs; 46 } 47 int getans2(int aa,int bb) 48 { 49 int p1=pos[aa],p2=pos[bb],gs=0,i; 50 if(p1==p2) 51 { 52 for(i=aa;i<=bb;i++)if(tot[i]!=0)gs++; 53 return gs; 54 } 55 for(i=aa;i<=p1*block;i++)if(tot[i]!=0)gs++; 56 for(i=p1+1;i<=p2-1;i++)gs+=num[i]; 57 for(i=(p2-1)*block+1;i<=bb;i++)if(tot[i]!=0)gs++; 58 return gs; 59 } 60 int write(int k) 61 { 62 if(k<0){putchar('-');k=-k;} 63 if(k>9)write(k/10); 64 putchar(k%10+'0'); 65 } 66 int main() 67 { 68 int n,m,i,L,R; 69 n=read();m=read(); 70 block=(int)sqrt(n); 71 for(i=1;i<=n;i++)color[i]=read(),pos[i]=(i-1)/block+1; 72 //block=(int)sqrt(n); 73 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; 74 //for(i=1;i<=n;i++)pos[i]=(i-1)/block+1; 75 sort(q+1,q+m+1,cmp); 76 L=1;R=0; 77 //memset(tot,0,sizeof(tot));//当前枚举的区间中每种颜色的个数. 78 //memset(sum,0,sizeof(sum));//每一块的总共的数量. 79 //memset(num,0,sizeof(num));//每一块的颜色的数量. 80 for(i=1;i<=m;i++) 81 { 82 while(L<q[i].l) 83 { 84 Del(color[L]); 85 L++; 86 } 87 while(L>q[i].l) 88 { 89 L--; 90 Add(color[L]); 91 } 92 while(R<q[i].r) 93 { 94 R++; 95 Add(color[R]); 96 } 97 while(R>q[i].r) 98 { 99 Del(color[R]); 100 R--; 101 } 102 ans1[q[i].id]=getans1(q[i].a,q[i].b); 103 ans2[q[i].id]=getans2(q[i].a,q[i].b); 104 } 105 for(i=1;i<=m;i++){write(ans1[i]);putchar(' ');write(ans2[i]);putchar('\n');}//printf("%d %d\n",ans1[i],ans2[i]); 106 return 0; 107 }