• bzoj 2141: 排队


    就是求个动态区间逆序对??是不是和GTY文艺妹子差不多??哦,不是,,,

    这个题的话,可以发现的是,每次交换只会对区间内的数产生影响,所以就是求一下区间内比这个L(区间左端点)大的,小的,(减小,加大)比R(区间右端点)大的,小的,(减大,加小),然后把两个数换一下就就行了(当然也要判断这两个数的逆序对变化)。。我记得是这样。。而且这个sb题也是调了好久、、、

      1 #include<bits/stdc++.h>
      2 #define N 100005
      3 #define LL long long
      4 #define inf 0x3f3f3f3f
      5 using namespace std;
      6 inline int ra()
      7 {
      8     int x=0,f=1; char ch=getchar();
      9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
     11     return x*f;
     12 }
     13 const int M=5000005;
     14 int a[N],sz,n,ans;
     15 int ls[M],rs[M],s[M],w[M],v[M],rnd[M],root[M];
     16 void update(int k){s[k]=s[ls[k]]+s[rs[k]]+w[k];}
     17 void rturn(int &k){int t=ls[k]; ls[k]=rs[t]; rs[t]=k; s[t]=s[k]; update(k); k=t;}
     18 void lturn(int &k){int t=rs[k]; rs[k]=ls[t]; ls[t]=k; s[t]=s[k]; update(k); k=t;}
     19 void insert(int &k, int num)
     20 {
     21     if (!k) {
     22         k=++sz; w[k]=s[k]=1; ls[k]=rs[k]=0; v[k]=num; rnd[k]=rand(); return;
     23     }
     24     s[k]++;
     25     if (num==v[k]) w[k]++;
     26     else if (num<v[k]) {insert(ls[k],num); if (rnd[ls[k]]<rnd[k]) rturn(k); }
     27     else {insert(rs[k],num); if (rnd[rs[k]]<rnd[k]) lturn(k);}
     28 }
     29 void del(int &k, int num)
     30 {
     31     if (v[k]==num)
     32     {
     33         if (w[k]>1) {s[k]--; w[k]--; return;}
     34         if (ls[k]*rs[k]==0) k=ls[k]+rs[k];
     35         else {if (rnd[ls[k]]<rnd[rs[k]]) rturn(k), del(k,num);
     36                 else lturn(k),del(k,num);
     37         }
     38     }
     39     else if (num<v[k]) del(ls[k],num),s[k]--;
     40         else del(rs[k],num),s[k]--;
     41 }
     42 void build(int k, int l, int r, int x, int num)
     43 {
     44     insert(root[k],num);
     45     if (l==r) return;
     46     int mid=l+r>>1;
     47     if (x<=mid) build(k<<1,l,mid,x,num);
     48     else build(k<<1|1,mid+1,r,x,num);
     49 }
     50 int find1(int k, int num)
     51 {
     52     if (!k) return 0;
     53     if (num==v[k]) return s[ls[k]];
     54     else if (num<v[k]) return find1(ls[k],num);
     55     else return w[k]+s[ls[k]]+find1(rs[k],num);
     56 }
     57 int ask1(int k ,int l, int r, int x, int y, int num)
     58 {
     59     if (l>r || x>y) return 0; 
     60     if (l==x && y==r) return find1(root[k],num);
     61     int mid=l+r>>1;
     62     if (y<=mid) return ask1(k<<1,l,mid,x,y,num);
     63     else if (x>mid) return ask1(k<<1|1,mid+1,r,x,y,num);
     64     else return ask1(k<<1,l,mid,x,mid,num)+ask1(k<<1|1,mid+1,r,mid+1,y,num);
     65 }
     66 int find(int k, int num)
     67 {
     68     if (!k) return 0;
     69     if (num==v[k]) return s[ls[k]]+w[k];
     70     else if (num<v[k]) return find(ls[k],num);
     71     else return w[k]+s[ls[k]]+find(rs[k],num);
     72 }
     73 int ask(int k ,int l, int r, int x, int y, int num)
     74 {
     75     if (l>r || x>y) return 0; 
     76     if (l==x && y==r) return find(root[k],num);
     77     int mid=l+r>>1;
     78     if (y<=mid) return ask(k<<1,l,mid,x,y,num);
     79     else if (x>mid) return ask(k<<1|1,mid+1,r,x,y,num);
     80     else return ask(k<<1,l,mid,x,mid,num)+ask(k<<1|1,mid+1,r,mid+1,y,num);
     81 }
     82 void change(int k, int l, int r, int pos, int old, int num)
     83 {
     84     del(root[k],old); insert(root[k],num);
     85     if (l==r) return;
     86     int mid=l+r>>1;
     87     if (pos<=mid) change(k<<1,l,mid,pos,old,num);
     88     else change(k<<1|1,mid+1,r,pos,old,num);
     89 }
     90 int main()
     91 {
     92     n=ra(); 
     93     for (int i=1; i<=n; i++) 
     94     {
     95         a[i]=ra();
     96         build(1,1,n,i,a[i]);
     97         ans+=(i-1-ask(1,1,n,1,i-1,a[i]));
     98     //    cout<<(i-1-ask(1,1,n,1,i-1,a[i]))<<endl;
     99     }
    100     printf("%d
    ",ans);
    101     int m=ra();
    102     while (m--)
    103     {
    104         int x=ra(),y=ra();
    105         if (x>y) swap(x,y);
    106         if (a[x]>a[y]) ans--; if (a[x]<a[y]) ans++;
    107         ans+=ask(1,1,n,x+1,y-1,a[y])+ask1(1,1,n,x+1,y-1,a[y])-ask(1,1,n,x+1,y-1,a[x])-ask1(1,1,n,x+1,y-1,a[x]);
    108         change(1,1,n,x,a[x],a[y]); change(1,1,n,y,a[y],a[x]);
    109         swap(a[x],a[y]);
    110     //    for (int i=1; i<=n; i++) printf("%d ",a[i]); cout<<endl;
    111         printf("%d
    ",ans);
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    python写的百度贴吧相册下载
    C#的图片拼接
    删除目录下的所有".svn"文件
    centOS 6.5 yum升级 gcc4.8 然后又退回来4.4
    代理的分类简述特点
    GCC 特性整理
    纯C 实现 strpos substr strspilt str_trim
    编译putty 源码去掉 Are you sure you want to close this session? 提示
    OpenWrt tcpdump 抓包
    安卓 打飞机 app 开发 第一篇
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6481072.html
Copyright © 2020-2023  润新知