BZOJ 3236: [Ahoi2013]作业
3236: [Ahoi2013]作业
Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1438 Solved: 577
[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
分析:
裸的莫队...
需要提醒的是a可能是负数...
代码:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 //by NeighThorn 7 using namespace std; 8 9 const int maxn=100000+5,maxm=1000000+5; 10 11 int n,m,blo,c[maxn],id[maxn],tr[2][maxn],cnt[maxn]; 12 13 struct M{ 14 int l,r,a,b,num,ans1,ans2; 15 }q[maxm]; 16 17 inline int read(void){ 18 char ch=getchar();int x=0,f=1; 19 while(!(ch>='0'&&ch<='9')){ 20 if(ch=='-')f=-1; 21 ch=getchar(); 22 } 23 while(ch>='0'&&ch<='9') 24 x=x*10+ch-'0',ch=getchar(); 25 return x*f; 26 } 27 28 inline bool cmp1(const M &x,const M &y){ 29 if(id[x.l]==id[y.l]) 30 return x.r<y.r; 31 return x.l<y.l; 32 } 33 34 inline bool cmp2(const M &x,const M &y){ 35 return x.num<y.num; 36 } 37 38 inline void insert(int k,int x,int y){ 39 for(;x<=n;x+=x&(-x)) 40 tr[k][x]+=y; 41 } 42 43 inline int query(int k,int x){ 44 if(x<=0) 45 return 0; 46 int res=0; 47 for(;x;x-=x&(-x)) 48 res+=tr[k][x]; 49 return res; 50 } 51 52 inline void change(int pos,int x){ 53 insert(0,c[pos],x);cnt[c[pos]]+=x; 54 if(cnt[c[pos]]==0&&x==-1) 55 insert(1,c[pos],-1); 56 else if(cnt[c[pos]]==1&&x==1) 57 insert(1,c[pos],1); 58 } 59 60 signed main(void){ 61 memset(cnt,0,sizeof(cnt)); 62 memset(tr,0,sizeof(tr)); 63 n=read();m=read();blo=(int)(sqrt(n)); 64 memset(cnt,0,sizeof(cnt)); 65 for(int i=1;i<=n;i++) 66 c[i]=read(),id[i]=(i-1)/blo+1; 67 for(int i=1;i<=m;i++) 68 q[i].l=read(),q[i].r=read(),q[i].a=read(),q[i].b=read(),q[i].num=i; 69 sort(q+1,q+m+1,cmp1); 70 for(int i=1,l=q[1].l,r=q[1].l-1;i<=m;i++){ 71 for(;l<q[i].l;l++) 72 change(l,-1); 73 for(;l>q[i].l;l--) 74 change(l-1,1); 75 for(;r<q[i].r;r++) 76 change(r+1,1); 77 for(;r>q[i].r;r--) 78 change(r,-1); 79 q[i].ans1=query(0,q[i].b)-query(0,q[i].a-1); 80 q[i].ans2=query(1,q[i].b)-query(1,q[i].a-1); 81 } 82 sort(q+1,q+m+1,cmp2); 83 for(int i=1;i<=m;i++) 84 printf("%d %d\n",q[i].ans1,q[i].ans2); 85 return 0; 86 }
by NeighThorn