zoukankan      html  css  js  c++  java
  • 【BZOJ】【3295】【CQOI2011】动态逆序对

    树套树


      Orz zyf神犇

      时光倒流……逆序处理,将删点改为加点,动态维护序列。

      由于是动态,要加点,所以用树状数组;同时又需要求序列中求比当前元素大/小的元素个数,所以要用平衡树。

      所以方法就是在树状数组的每个节点上维护一棵这个节点表示的区间的平衡树。

      为什么这样做是对的呢?因为求<k的元素个数这类操作满足区间加法,所以可以把多棵平衡树上的结果(一棵平衡树表示一个区间)加起来,就是整个区间的结果。

    (我一开始想成带修改的区间第K大那种做法了……就是树状数组套权值线段树……sigh)

    WA:ans[m+1]需要初始化,样例是因为只剩一个数所以逆序对数为0,但是其他数据明显不会是这样……

      1 /**************************************************************
      2     Problem: 3295
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:8432 ms
      7     Memory:122372 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 3295
     11 #include<cmath>
     12 #include<vector>
     13 #include<cstdio>
     14 #include<cstring>
     15 #include<cstdlib>
     16 #include<iostream>
     17 #include<algorithm>
     18 #define rep(i,n) for(int i=0;i<n;++i)
     19 #define F(i,j,n) for(int i=j;i<=n;++i)
     20 #define D(i,j,n) for(int i=j;i>=n;--i)
     21 #define pb push_back
     22 #define CC(a,b) memset(a,b,sizeof(a))
     23 using namespace std;
     24 int getint(){
     25     int v=0,sign=1; char ch=getchar();
     26     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
     27     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
     28     return v*sign;
     29 }
     30 const int N=100010,M=5000010,INF=~0u>>2;
     31 const double eps=1e-8;
     32 typedef long long LL;
     33 /*******************template********************/
     34 int n,m,tot,l[M],r[M],s[M],rnd[M],w[M],v[M];
     35 #define L l[x]
     36 #define R r[x]
     37 inline void Push_up(int x){
     38     s[x]=s[L]+s[R]+w[x];
     39 }
     40 inline void zig(int &x){
     41     int t=L; L=r[t]; r[t]=x; s[t]=s[x]; Push_up(x); x=t;
     42 }
     43 inline void zag(int &x){
     44     int t=R; R=l[t]; l[t]=x; s[t]=s[x]; Push_up(x); x=t;
     45 }
     46 void ins(int &x,int num){
     47     if (!x){
     48         x=++tot; v[x]=num; s[x]=w[x]=1; L=R=0; rnd[x]=rand(); return;
     49     }
     50     s[x]++;
     51     if (v[x]==num) w[x]++;
     52     else if(num<v[x]){
     53         ins(L,num); if(rnd[L]<rnd[x]) zig(x);
     54     }else{
     55         ins(R,num); if(rnd[R]<rnd[x]) zag(x);
     56     }
     57 }
     58 int rank(int x,int num){//比x小的数有多少个
     59     if (!x) return 0;
     60     if (v[x]==num) return s[L];
     61     else if(num<v[x]) return rank(L,num);
     62     else return s[L]+w[x]+rank(R,num);
     63 }
     64 #undef L
     65 #undef R
     66 /**********************Treap********************/
     67 int rt[N];
     68 int ss[N];
     69 void update(int x,int y){
     70     for(int i=x;i<=n;i+=i&-i) ins(rt[i],y);
     71 }
     72 LL getbig(int x,int val){
     73     int t=0;
     74     for(int i=x;i;i-=i&-i)
     75         t+=s[rt[i]]-rank(rt[i],val);
     76     return t;
     77 }
     78 LL getsml(int x,int y,int val){
     79     int t1=0,t2=0;
     80     for(int i=x;i;i-=i&-i)
     81         t1+=rank(rt[i],val);
     82     for(int j=y;j;j-=j&-j)
     83         t2+=rank(rt[j],val);
     84     return t2-t1;
     85 }
     86 void add(int x){
     87     for(int i=x;i<=n;i+=i&-i) ss[i]++;
     88 }
     89 LL sum(int x){
     90     int ans=0;
     91     for(int i=x;i;i-=i&-i) ans+=ss[i];
     92     return ans;
     93 }
     94 /*********************Fenwick*******************/
     95 struct data{
     96     int v,pos;
     97     bool operator < (const data&b) const{
     98         return v<b.v;
     99     }
    100 }a[N],b[N],d[N];
    101 LL ans[N];
    102 int main(){
    103 #ifndef ONLINE_JUDGE
    104     freopen("input.txt","r",stdin);
    105 //  freopen("output.txt","w",stdout);
    106 #endif
    107     n=getint(); m=getint();
    108     F(i,1,n) a[i].v=getint(),a[i].pos=i,b[i]=a[i];
    109     sort(b+1,b+n+1);
    110     F(i,1,m){
    111         d[i].v=getint();
    112         d[i].pos=b[d[i].v].pos;
    113     }
    114     F(i,1,n) b[i]=a[i];
    115     F(i,1,m) b[d[i].pos].v=0;
    116     ans[m+1]=0;
    117  
    118     F(i,1,n) if (b[i].v){
    119         update(i,b[i].v);
    120         ans[m+1]+=sum(n)-sum(b[i].v);
    121         add(b[i].v);
    122     }
    123      
    124     D(i,m,1){
    125         ans[i]=ans[i+1]+getbig(d[i].pos-1,d[i].v)+getsml(d[i].pos,n,d[i].v);
    126         update(d[i].pos,d[i].v);
    127     }
    128     F(i,1,m) printf("%lld
    ",ans[i]);
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    懂一点Python系列——快速入门
    DatagridView 控件列顺序与设置的不一样
    WinForm Column cannot be added because its CellType property is null.
    Rabbitmq消息服务器通讯异常: name must not be blank
    Redis 数据库
    redis 安装与使用
    windows 服务的安装与卸载之bat脚本命令
    以超级管理员方式运行bat文件
    CMD 下切换目录
    C#导出Excel后关闭进程EXCEL.EXE
  • 原文地址:https://www.cnblogs.com/Tunix/p/4342819.html
Copyright © 2011-2022 走看看