BZOJ3809: Gty的二逼妹子序列

来源:互联网 发布:ubuntu添加软件源 编辑:程序博客网 时间:2024/04/29 08:07

莫队
哈。。。。一开始没注意用树状数组。。。妥妥的TTTTT
然后才改了分块

lowbit(T)

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const   int maxn=100001;int Pos[maxn];int T[maxn*2];int n,m;inline int lowbit(int x){return x&-x;}inline void add(int x){for(int i=x;i<=n*2;i+=lowbit(i))T[i]++;}inline void del(int x){for(int i=x;i<=n*2;i+=lowbit(i))T[i]--;}inline int query(int x){int ans=0;for(int i=x;i;i^=lowbit(i))ans+=T[i];return ans;}struct Que{int x,a,b,y,id,ans;inline friend bool operator <(Que a,Que b){return a.id<b.id;}};inline bool cmp(Que a,Que b){return Pos[a.x]^Pos[b.x]?Pos[a.x]<Pos[b.x]:a.y<b.y;}char c;inline void read(int &a){    a=0;do c=getchar();while(c<'0'||c>'9');    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}Que Line[maxn*10];int s[maxn];int con[maxn];int main(){    int i,j,k,l;    read(n),read(m);    int size=sqrt(n);       for(i=1;i<=n;i++)           Pos[i]=i/size,read(s[i]);    for(i=1;i<=m;i++)     read(Line[i].x),     read(Line[i].y),     read(Line[i].a),     read(Line[i].b),     Line[i].id=i;    sort(Line+1,Line+1+m,cmp);    l=1;int r=0;    for(i=1;i<=m;i++)       {          Que tp=Line[i];          while(r<tp.y)             {++r;if(!con[s[r]])add(s[r]);con[s[r]]++;}         while(l>tp.x)             {l--;if(!con[s[l]])add(s[l]);con[s[l]]++;}         while(l<tp.x)             {con[s[l]]--;if(!con[s[l]])del(s[l]);l++;}          while(r>tp.y)             {con[s[r]]--;if(!con[s[r]])del(s[r]);r--;}          Line[i].ans=query(tp.b)-query(tp.a-1);       }    sort(Line+1,Line+1+m);    for(int i=1;i<=m;i++)     printf("%d\n",Line[i].ans);    return 0;}

分块

#include<iostream>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const   int maxn=100001;int Pos[maxn];int n,m;struct Que{int x,a,b,y,id,ans;inline friend bool operator <(Que a,Que b){return a.id<b.id;}};inline bool cmp(Que a,Que b){return Pos[a.x]^Pos[b.x]?Pos[a.x]<Pos[b.x]:a.y<b.y;}char c;inline void read(int &a){    a=0;do c=getchar();while(c<'0'||c>'9');    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}Que Line[maxn*10];int s[maxn];int con[maxn];int size;int a[400];inline void del(int x){a[x/size]--;}inline void add(int x){a[x/size]++;}inline int query(int x,int y){    int ans=0;    int i,mp=(x/size+1)*size;    if(Pos[x]^Pos[y])    {    if(!(Pos[x]^Pos[x-1]))    for(i=x;i<mp;i++)      ans+=con[i]==0?0:1;    for(i=Pos[x]+(Pos[x]^Pos[x-1]?0:1);i<=Pos[y];i++)       ans+=a[i];    for(i=min((Pos[y]+1)*size-1,n);i>y;i--)       ans-=con[i]==0?0:1;       return ans;     }    for(i=x;i<=y;i++)      ans+=con[i]==0?0:1;   return ans;}int main(){    int i,j,k,l;    read(n),read(m);    size=sqrt(n);        Pos[0]=0;    for(i=1;i<=n;i++)          Pos[i]=i/size,read(s[i]);    for(i=1;i<=m;i++)     read(Line[i].x),     read(Line[i].y),     read(Line[i].a),     read(Line[i].b),     Line[i].id=i;    sort(Line+1,Line+1+m,cmp);    l=1;int r=0;    for(i=1;i<=m;i++)       {          Que tp=Line[i];          while(r<tp.y)             {++r;if(!con[s[r]])add(s[r]);con[s[r]]++;}         while(l>tp.x)             {l--;if(!con[s[l]])add(s[l]);con[s[l]]++;}         while(l<tp.x)             {con[s[l]]--;if(!con[s[l]])del(s[l]);l++;}          while(r>tp.y)             {con[s[r]]--;if(!con[s[r]])del(s[r]);r--;}          Line[i].ans=query(tp.a,tp.b);       }    sort(Line+1,Line+1+m);    for(int i=1;i<=m;i++)     printf("%d\n",Line[i].ans);    return 0;}
0 0