[bzoj3809] Gty的二逼妹子序列

  莫队+分块。。分块修改O(1),查询O(n^0.5)

  总复杂度O(n^1.5)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define ll long long
 7 using namespace std;
 8 const int maxn=100233;
 9 struct zs{int l,r,a,b,id;}q[1002333];
10 int B[maxn],a[maxn],mp[maxn],l[maxn],r[maxn];
11 int ans[1002333];
12 int sz[2333];
13 int i,j,k,n,m,kuai;
14  
15 int ra;char rx;
16 inline int read(){
17     rx=getchar(),ra=0;
18     while(rx<'0'||rx>'9')rx=getchar();
19     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
20 }
21  
22 inline void add(int x){sz[B[x]]+=!mp[x],mp[x]++;}
23 inline void del(int x){mp[x]--,sz[B[x]]-=!mp[x];}
24 inline int query(int a,int b){
25     register int i;int sm=0,idl=B[a],idr=B[b];
26     if(idl==idr){
27         for(i=a;i<=b;i++)sm+=mp[i]>0;
28         return sm;
29     }
30     for(i=a;i<=r[idl];i++)sm+=mp[i]>0;
31     for(i=l[idr];i<=b;i++)sm+=mp[i]>0;
32     for(i=idl+1;i<idr;i++)sm+=sz[i];
33     return sm;
34 }
35  
36 bool cmp(zs a,zs b){return B[a.l]==B[b.l]?((B[a.l]&1)?a.r<b.r:a.r>b.r):B[a.l]<B[b.l];}
37 int main(){
38     n=read(),m=read();kuai=(int)sqrt(n)+3;
39     for(i=1;i<=n;i++)a[i]=read(),B[i]=(i+kuai-1)/kuai;
40     for(i=1;i<=B[n];i++)
41         l[i]=(i-1)*kuai+1,r[i]=i==B[n]?n:(l[i]+kuai-1);
42     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;
43     sort(q+1,q+1+m,cmp);
44     register int l=1,r=0;
45     for(i=1;i<=m;i++){
46         while(l>q[i].l)l--,add(a[l]);
47         while(r<q[i].r)r++,add(a[r]);
48         while(l<q[i].l)del(a[l]),l++;
49         while(r>q[i].r)del(a[r]),r--;
50         ans[q[i].id]=query(q[i].a,q[i].b);
51     }
52     for(i=1;i<=m;i++)printf("%d\n",ans[i]);
53     return 0;
54 }
View Code

 

posted @ 2016-06-18 17:05  czllgzmzl  阅读(262)  评论(0编辑  收藏  举报