zoukankan      html  css  js  c++  java
  • [BZOJ3295][CQOI2011]动态逆序对 树套树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3295

    观察可得,每一次答案减少的就是,这个数之前比它大的数的个数,这个数之后比它小的数的个数。

    所以我们用树状数组来确保这个数前后的区间查询,用权值线段树求其代表的一个区间内比$x$大或小的数的个数。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 int inline readint(){
     7     int Num;char ch;
     8     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
     9     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
    10     return Num;
    11 }
    12 void outll(ll x){
    13     if(x>=10) outll(x/10);
    14     putchar(x%10+'0');
    15 }
    16 int N,M;
    17 int pos[100010];
    18 int inline lowbit(int &x){
    19     return x&-x;
    20 }
    21 int Rt[100010],lc[10000000],rc[10000000],num[10000000],cnt=0;
    22 void Insert(int &rt,int l,int r,int x){
    23     if(!rt) rt=++cnt;
    24     num[rt]++;
    25     if(l==r) return;
    26     int mid=l+r>>1;
    27     if(x<=mid) Insert(lc[rt],l,mid,x);
    28     else Insert(rc[rt],mid+1,r,x);
    29 }
    30 int Qry(int &rt,int l,int r,int L,int R){
    31     if(!rt) return 0;
    32     if(l>=L&&r<=R) return num[rt];
    33     int mid=l+r>>1,ret=0;
    34     if(L<=mid) ret=Qry(lc[rt],l,mid,L,R);
    35     if(R>mid) ret+=Qry(rc[rt],mid+1,r,L,R);
    36     return ret;
    37 }
    38 void Del(int &rt,int l,int r,int x){
    39     if(!rt) return;
    40     num[rt]--;
    41     if(l==r) return;
    42     int mid=l+r>>1;
    43     if(x<=mid) Del(lc[rt],l,mid,x);
    44     else Del(rc[rt],mid+1,r,x);
    45 }
    46 ll Ans=0;
    47 int main(){
    48     N=readint();
    49     M=readint();
    50     for(int i=1;i<=N;i++){
    51         int x=readint();
    52         pos[x]=i;
    53         for(int j=i;j<=N;j+=lowbit(j))
    54             Insert(Rt[j],1,N,x);
    55         if(x!=N)
    56             for(int j=i;j>=1;j-=lowbit(j))
    57                 Ans+=Qry(Rt[j],1,N,x+1,N);
    58     }
    59     for(int i=1;i<=M;i++){
    60         outll(Ans);
    61         putchar('
    ');
    62         int x=readint();
    63         if(x!=N)
    64             for(int j=pos[x];j>=1;j-=lowbit(j))
    65                 Ans-=Qry(Rt[j],1,N,x+1,N);
    66         if(x!=1){
    67             for(int j=N;j>=1;j-=lowbit(j))
    68                 Ans-=Qry(Rt[j],1,N,1,x-1);
    69             for(int j=pos[x]-1;j>=1;j-=lowbit(j))
    70                 Ans+=Qry(Rt[j],1,N,1,x-1);
    71         }
    72         for(int j=pos[x];j<=N;j+=lowbit(j))
    73             Del(Rt[j],1,N,x);
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    种类并查集
    因式分解
    最长递增(不减)子序列
    C++之算法题模板
    线段树
    C++之环境搭建
    C++之vector用法
    逆序数以及右边更小数的个数
    Unity3d之动态连接Mesh Renderer和Collider
    Matlab之字符串处理
  • 原文地址:https://www.cnblogs.com/halfrot/p/7666154.html
Copyright © 2011-2022 走看看