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

    P3157 [CQOI2011]动态逆序对

    https://www.luogu.org/problemnew/show/P3157

    题目描述

    对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

    输入输出格式

    输入格式:

    输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。

    输出格式:

    输出包含m行,依次为删除每个元素之前,逆序对的个数。

    输入输出样例

    输入样例#1: 
    5 4
    1
    5
    3
    4
    2
    5
    1
    4
    2
    输出样例#1: 
    5
    2
    2
    1
    
    样例解释
    (1,5,3,4,2) (1,3,4,2) (3,4,2) (3,2) (3)。

    说明

    N<=100000 M<=50000

    树状数组套主席树

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<set>
      7 #include<map>
      8 #include<vector>
      9 #include<queue>
     10 #define N 100005
     11 using namespace std;
     12 
     13 struct sair{
     14     int l,r,sum;
     15 }tree[N*150];
     16 int n;
     17 int root[N],a[N],b[N],c[N],cnt;
     18 void Add(int x){
     19     while(x<=n){
     20         c[x]++;
     21         x+= x&(-x);
     22     }
     23 }
     24 
     25 int getsum(int x){
     26     int sum=0;
     27     while(x){
     28         sum+=c[x];
     29         x-= x&(-x);
     30     }
     31     return sum;
     32 }
     33 
     34 void add(int cur,int l,int r,int p,int v){
     35     tree[cur].sum+=v;
     36     if(l==r){
     37         return;
     38     }
     39     int mid=(l+r)/2;
     40     if(p<=mid){
     41         if(!tree[cur].l){
     42             tree[cur].l=++cnt;
     43         }
     44         add(tree[cur].l,l,mid,p,v);
     45     }
     46     else{
     47         if(!tree[cur].r){
     48             tree[cur].r=++cnt;
     49         }
     50         add(tree[cur].r,mid+1,r,p,v);
     51     }
     52 }
     53 
     54 int query(int L,int R,int cur,int l,int r){
     55     if(!cur){
     56         return 0;
     57     }
     58     if(L<=l&&R>=r){
     59         return tree[cur].sum;
     60     }
     61     int mid=(l+r)/2;
     62     int ans=0;
     63     if(L<=mid) ans+=query(L,R,tree[cur].l,l,mid);
     64     if(R>mid) ans+=query(L,R,tree[cur].r,mid+1,r);
     65     return ans;
     66 }
     67 
     68 int main(){
     69     int m,v,p,j;
     70     scanf("%d %d",&n,&m);
     71     long long ans=0;
     72     for(int i=1;i<=n;i++){
     73         scanf("%d",&a[i]);
     74         b[a[i]]=i;
     75         Add(a[i]);
     76         ans+=getsum(n)-getsum(a[i]);
     77         for(j=i;j<=n;j+= j&(-j)){
     78             if(!root[j]){
     79                 root[j]=++cnt;
     80             }
     81             add(root[j],1,n,a[i],1);
     82         }
     83     }
     84     for(int i=1;i<=m;i++){
     85         printf("%lld
    ",ans);
     86         scanf("%d",&v);
     87         p=b[v];
     88         j=p-1;
     89         while(j){
     90             ans-=query(v+1,n,root[j],1,n);
     91             j-= j&(-j);
     92         }
     93         j=n;
     94         while(j){
     95             ans-=query(1,v-1,root[j],1,n);
     96             j-= j&(-j);
     97         }
     98         j=p;
     99         while(j){
    100             ans+=query(1,v-1,root[j],1,n);
    101             j-= j&(-j);
    102         }
    103         j=p;
    104         while(j<=n){
    105             add(root[j],1,n,v,-1);
    106             j+= j&(-j);
    107         }
    108     }
    109 }
    View Code
  • 相关阅读:
    Linux常见命令
    关于SpringBoot开发微信模板推送
    SpringBoot使用ModelAndView时配置视图解析器
    自定义SpringBoot控制台输出的图案
    关于Maven整合SSM项目中报错Invalid bound statement (not found):的问题解决
    Mysql 经典案例总结(学习之前需要有Mysql基础)01
    认识Java Spring 框架
    设计模式1--简单工厂
    C#中扩展方法
    苹果MDM原理和实现过程
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/9748857.html
Copyright © 2011-2022 走看看