zoukankan      html  css  js  c++  java
  • [填坑]一直遗忘的树套树版本动态CDQ

    题解: 树状数组维护动态开点线段树 实质上是树状数组对应区间维护一颗动态开点线段树 方便对应区间小于x的个数

    #include <bits/stdc++.h>
    #define ll long long
    const int MAXN=1e5+10;
    using namespace std;
    ll read(){  
        ll x=0,f=1;char ch=getchar();  
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}  
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();  
        return f*x;
    }
    typedef struct node{
        int l,r,sum;
    }node;
    vector<int>vec;
    node d[MAXN*85];
    int a[MAXN],n,m,cnt,id[MAXN],rt[MAXN];
    int get_id(int x){return x&(-x);}
    void csh(int x){
        for(int i=x;i<=n;i+=get_id(i))vec.push_back(i);
    }
    void csh1(int x){
        for(int i=x;i>0;i-=get_id(i))vec.push_back(i);
    }
    void update(int &x,int l,int r,int t,int vul){
        if(!x)x=++cnt;
        d[x].sum+=vul;
        if(l==r)return ;
        int mid=(l+r)>>1;
        if(t<=mid)update(d[x].l,l,mid,t,vul);
        else update(d[x].r,mid+1,r,t,vul);
    }
    ll ans=0;
    void querty(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            ans+=d[x].sum;return ;
        }
        int mid=(l+r)>>1;
        if(ql<=mid)querty(d[x].l,l,mid,ql,qr);
        if(qr>mid)querty(d[x].r,mid+1,r,ql,qr);
    }
    int p[MAXN];
    void add(int x){
        for(;x<=n;x+=get_id(x))p[x]++;
    }
    int Sum(int x){
        int ans1=0;
        for(;x>0;x-=get_id(x))ans1+=p[x];
        return ans1;
    }
    int main(){
        n=read();m=read();cnt=0;
        for(int i=1;i<=n;i++)a[i]=read(),id[a[i]]=i;ll sum=0;
        for(int i=1;i<=n;i++){
            csh(i);
            for(int j=0;j<vec.size();j++)update(rt[vec[j]],1,n,a[i],1);
            vec.clear();
            if(a[i]==n)continue;
            csh1(i);
            for(int j=0;j<vec.size();j++)ans=0,querty(rt[vec[j]],1,n,a[i]+1,n),sum+=ans;
            vec.clear(); 
        }
        int t;ll num,num1,num2;
        printf("%lld
    ",sum);
        for(int i=1;i<min(n,m);i++){   
            t=read();
            csh1(id[t]);num=0,num1=0;
            if(t!=n){for(int j=0;j<vec.size();j++)ans=0,querty(rt[vec[j]],1,n,t+1,n),num+=ans;}
            if(t!=1){for(int j=0;j<vec.size();j++)ans=0,querty(rt[vec[j]],1,n,1,t-1),num1+=ans;}
            vec.clear();
            sum-=num+t-1-num1-Sum(t);
            csh(id[t]);
            for(int j=0;j<vec.size();j++)update(rt[vec[j]],1,n,t,-1);
            vec.clear();
            add(t);printf("%lld
    ",sum);
        }
        return 0;
    }
    

    3295: [Cqoi2011]动态逆序对

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 7107  Solved: 2526
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    5 4
    1
    5
    3
    4
    2
    5
    1
    4
    2

    Sample Output

    5
    2
    2
    1
    样例解释
    (1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。

  • 相关阅读:
    HTML 折行 <br/>标签
    HTML 图像<img>
    HTML 段落<p>标签
    vuecli实现最简单的全选、全不选、反选功能。不容错过呦!!!!!话不多说直接上代码。。。。
    CListCtrl使用方法
    求素数
    hdr lighting step 4 最终结果
    ASCII效果
    镜子中的物体为什么是左右颠倒而非上下颠倒的?
    hdr lighting step 1 tone map
  • 原文地址:https://www.cnblogs.com/wang9897/p/9490973.html
Copyright © 2011-2022 走看看