• 动态逆序对[CQOI2011]


    此题正解 树套树
    &&CDQ也要会啦

    洛谷

    首先按删除顺序,给每个点赋时间值,没删的赋inf
    按时间从小到大排序,后删除的对先删除的莫得贡献,但是先删除的对后删除的有贡献

    第二维 按pos值从小到大排序

    维护两个东西
    {posi<posj&&vali>valj}

    {posi>posj&&vali<valj}

    然后 莫得了

    #include<bits/stdc++.h>
    #define re return
    #define lowbit(x) (x&(-x))
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    const int maxn=100005;
    using namespace std;
    template<typename T>inline void rd(T& x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    int n,m,c[maxn],pos[maxn],d[maxn];
    long long ans;
    
    struct node{
    	int timme,val,pos,ans;
    	bool operator<(node a)const
    	{re timme<a.timme;}
    }num[maxn],t[maxn];
    
    inline void add(int x,int y){while(x<=n){c[x]+=y;x+=lowbit(x);}} 
    inline int sum(int x)
    {
    	int res=0;
    	while(x)
    	{res+=c[x];x-=lowbit(x);}
    	re res;
    }
    
    inline void CDQ(int l,int r)
    {
    	if(l==r) re;
    	int mid=(l+r)>>1;
    	CDQ(l,mid),CDQ(mid+1,r);
    	int q=r,tot=l;
    	dec(i,mid,l)
    	{
    		while(q>mid&&num[q].pos>num[i].pos)add(num[q].val,1),--q;
    		num[i].ans+=sum(num[i].val-1);
    	}
    	inc(i,q+1,r)add(num[i].val,-1);
    	
    	q=mid+1;
    	inc(i,l,mid)
    	{
    		while(q<=r&&num[q].pos<num[i].pos)
    		{
    			add(num[q].val,1);
    			t[tot++]=num[q];
    			++q;
    		}
    		num[i].ans+=sum(n)-sum(num[i].val);
    		t[tot++]=num[i];
    	}
    	
    	inc(i,mid+1,q-1)add(num[i].val,-1);
    	inc(i,l,tot-1)num[i]=t[i];
    	inc(i,tot,r)num[i]=num[q++];
    }
    int main()
    {	
    	freopen("in.txt","r",stdin);
    	int x;
    	rd(n);rd(m);
    	inc(i,1,n)
    	{
    		rd(num[i].val);
    		num[i].pos=i;
    		pos[num[i].val]=i;
    		num[i].timme=n;
    	}
    	
    	inc(i,1,m)
    	{
    		rd(d[i]);
    		num[pos[d[i]]].timme=i;
    	}
    	
    	sort(num+1,num+n+1);
    	CDQ(1,n);
    	
    	
    	inc(i,1,n)ans+=num[i].ans;
    	
    	inc(i,1,m)
    	{
    		printf("%d
    ",ans);
    		ans-=num[pos[d[i]]].ans;
    	}
        re 0;
    } 
    
  • 相关阅读:
    Spring学习笔记
    deepin linux 下C开发环境配置
    deepin linux 15.3安装完eclipse启动报错An error has occurred.
    windows下安装vundle
    Tomcat 改服务器编码(Java 修改字符串编码格式)
    servlet request getQueryString 汉字的URI编码如何转码
    servlet request
    servlet awt随机图片验证码
    java获取unicode码
    技术总监
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11336775.html
Copyright © 2020-2023  润新知