BZOJ 3236: [Ahoi2013]作业

3236: [Ahoi2013]作业

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

Sample Output

2 2
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 }
View Code

by NeighThorn

posted @ 2016-12-20 20:10  NeighThorn  阅读(310)  评论(2编辑  收藏  举报