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

## 3236: [Ahoi2013]作业

Time Limit: 100 Sec  Memory Limit: 512 MB
Submit: 1113  Solved: 428
[Submit][Status][Discuss]

3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3

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];
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 }
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;
70     block=(int)sqrt(n);
72     //block=(int)sqrt(n);
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--;
91         }
92         while(R<q[i].r)
93         {
94             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  微弱的世界  阅读(202)  评论(0编辑  收藏  举报