【bzoj3744】GTY的妹子序列

大力分块+树状数组+主席树……

#include<bits/stdc++.h>
#define N 50005
#define pa pair<int,int>
#define fi first
#define sc second
using namespace std;
int n,m,cnt,tot,size,t;
int a[N],c[N],num[N],rt[N];
int sum[250][N];
inline int lowbit(int x){return (x&(-x));}
pa b[N];
struct Persistenable_Segment_Tree{
    int ls[20*N],rs[20*N],size[20*N],cnt;
    void ins(int &x,int pre,int l,int r,int q){
        x=++cnt;size[x]=size[pre]+1;
        if(l==r)return;
        ls[x]=ls[pre];rs[x]=rs[pre];
        int mid=(l+r)>>1;
        if(q<=mid)ins(ls[x],ls[pre],l,mid,q);
        else ins(rs[x],rs[pre],mid+1,r,q);
    }
    int query(int x,int pre,int l,int r,int ql,int qr){
        if(size[x]==size[pre])return 0;
        if(ql<=l&&r<=qr)return size[pre]-size[x];
        int mid=(l+r)>>1,ans=0;
        if(ql<=mid)ans+=query(ls[x],ls[pre],l,mid,ql,qr);
        if(qr>mid)ans+=query(rs[x],rs[pre],mid+1,r,ql,qr);
        return ans; 
    }
}T;
inline void add(int x,int val){
    for(int i=x;i<=tot;i+=lowbit(i))c[i]+=val;
}
inline int ask(int x){
    int ans=0;
    for(int i=x;i;i-=lowbit(i))ans+=c[i];
    return ans;
}
//bit
int query(int x,int y){
    int ans=0;
    if(num[x]==num[y]){
        memset(c,0,sizeof(c));
        for(int i=x;i<=y;++i)ans+=ask(tot)-ask(a[i]),add(a[i],1);
        return ans;
    }
    ans=sum[num[x]+1][y];
    for(register int i=x;i<=size*num[x];++i)ans+=T.query(rt[i],rt[y],1,tot,1,a[i]-1);
    return ans;
}
//block
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
int LastOrder=0;
int main(){
    n=read();size=round(sqrt(n));
    for(int i=1;i<=n;i++)b[i].fi=read(),b[i].sc=i;
    sort(b+1,b+n+1);
    for(int i=1;i<=n;i++){
        if(i==1|b[i].fi!=b[i-1].fi)++tot;
        a[b[i].sc]=tot;
    }
    for(int i=1;i<=n;i++)T.ins(rt[i],rt[i-1],1,tot,a[i]);
    for(int i=1;i<=n;i++)num[i]=(i-1)/size+1;
    for(int i=1;i<=num[n];i++){
        memset(c,0,sizeof(c));
        for(int j=(i-1)*size+1;j<=n;j++){
            sum[i][j]=sum[i][j-1]+ask(tot)-ask(a[j]);
            add(a[j],1);
        }
    }
    m=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read();x^=LastOrder;y^=LastOrder;
        LastOrder=query(x,y);
        printf("%d\n",LastOrder);
    }
    return 0;
}

 

posted @ 2017-06-03 19:47  zcysky  阅读(140)  评论(0编辑  收藏  举报