Bzoj 3236: [Ahoi2013]作业 莫队,分块

3236: [Ahoi2013]作业

Time Limit: 100 Sec  Memory Limit: 512 MB
Submit: 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

Sample Output

2 2
1 1
3 2
2 1

HINT

 

 


N=100000,M=1000000

 

Source

By wangyisong1996加强数据

题解:

莫队+分块乱搞。

  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 }

 

posted @ 2016-03-21 10:42  微弱的世界  阅读(252)  评论(0编辑  收藏  举报