BZOJ3809: Gty的二逼妹子序列

莫队
哈。。。。一开始没注意用树状数组。。。妥妥的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;
}

你可能感兴趣的:(BZOJ3809: Gty的二逼妹子序列)