[bzoj3744]Gty的妹子序列

来源:互联网 发布:ae mac 破解补丁 编辑:程序博客网 时间:2024/05/01 20:44

题目大意

在线兹瓷区间求逆序对个数。

双倍经验

最简单的做法是预处理ans和sum这个不用说了具体可以看根号算法题库里的经典分块思路。
当然这道题有升级版Gty的文艺妹子序列,那道题多一个修改操作。
反正我直接改了一下那题的代码交了。

#include<cstdio>#include<algorithm>#include<cmath>#include<ctime>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=50000+10,maxc=250+10;int ans[maxc][maxc],num[maxc];int sum[maxc][maxn],tree[maxn];int belong[maxn],a[maxn],b[maxn],sta[maxn];int i,j,k,l,r,s,t,n,m,now,top,c;bool czy;int lowbit(int x){    return x&-x;}void change(int k,int t){    while(k<=n){          tree[k]+=t;          k+=lowbit(k);      }  }int query(int k){    int t=0;      while (k){          t+=tree[k];          k-=lowbit(k);      }      return t;  }void change2(int id,int k,int t){    while(k<=belong[n]){          ans[id][k]+=t;          k+=lowbit(k);      }  }int query2(int id,int k){    int t=0;      while (k){          t+=ans[id][k];          k-=lowbit(k);      }      return t;  }void change3(int id,int k,int t){    while(k<=n){          sum[id][k]+=t;          k+=lowbit(k);      }  }int query3(int id,int k){    int t=0;      while (k){          t+=sum[id][k];          k-=lowbit(k);      }      return t;  }int read(){    int x=0;    char ch=getchar();    while (ch<'0'||ch>'9') ch=getchar();    while (ch>='0'&&ch<='9'){        x=x*10+ch-'0';        ch=getchar();    }    return x;}void write(int x){    while (x){        sta[++top]=x%10;        x/=10;    }    while (top){        putchar(sta[top]+'0');        top--;    }    putchar('\n');}int main(){    //freopen("data6.in","r",stdin);freopen("3787.out","w",stdout);    czy=1;    n=read();    c=floor(sqrt(n));    fo(i,1,n) a[i]=read(),b[i]=a[i],belong[i]=(i-1)/c+1;    sort(b+1,b+n+1);    l=unique(b+1,b+n+1)-b-1;    fo(i,1,n) a[i]=lower_bound(b+1,b+l+1,a[i])-b;    fo(i,1,belong[n]-1){        fo(j,(i-1)*c+1,i*c) change(a[j],1);        fo(j,i+1,belong[n]){            t=0;            fo(k,(j-1)*c+1,min(j*c,n)) t+=query(n)-query(a[k]);            change2(i,j,t);        }        fo(j,(i-1)*c+1,i*c) change(a[j],-1);    }    fo(i,1,belong[n])        fo(j,1,min(i*c,n)) change3(i,a[j],1);    fo(i,1,belong[n]){        fo(j,(i-1)*c+1,min(n,i*c)){            num[i]+=query(n)-query(a[j]);            change(a[j],1);        }        fo(j,(i-1)*c+1,min(n,i*c)) change(a[j],-1);    }    m=read();    while (m--){        j=read();k=read();        if (czy) j^=now,k^=now;        now=0;        l=belong[j];r=belong[k];        if (r-l<=1){            fo(i,j,k){                now+=query(n)-query(a[i]);                change(a[i],1);            }            fo(i,j,k) change(a[i],-1);                //write(now);            printf("%d\n",now);            continue;        }        fo(i,l+1,r-1){            now+=num[i];            now+=query2(i,r-1)-query2(i,i);        }        fo(i,j,l*c){            now+=query(n)-query(a[i]);            now+=query3(r-1,a[i]-1)-query3(l,a[i]-1);            change(a[i],1);        }        fo(i,(r-1)*c+1,k){            now+=query(n)-query(a[i]);            now+=query3(r-1,n)-query3(r-1,a[i])-query3(l,n)+query3(l,a[i]);            change(a[i],1);        }        fo(i,j,l*c) change(a[i],-1);        fo(i,(r-1)*c+1,k) change(a[i],-1);        //write(now);        printf("%d\n",now);    }    //printf("\n%d\n",clock());}
0 0