zoukankan      html  css  js  c++  java
  • [BZOJ2141]排队

    BZOJ
    Luogu
    题意:每次交换序列中的两个数,然后求逆序对数

    sol

    看一眼这不是动态逆序对嘛。
    所以就是一个裸的树套树呀
    树状数组套线段树
    修改的时候需要讨论一波交换的两个数的大小关系,设交换的两个位置是(a,b)(a<b)
    1、(h_a=h_b)

    ...

    2、(h_a<h_b)

    首先交换后(a,b)会贡献一对逆序对所以ans++
    对于位置在(a)前面或者(b)后面的数都没有影响
    对于处于(a,b)之间的数(i)
    (h_i=h_a)(h_i=h_b),那么交换后会产生1的贡献
    (h_a<h_i<h_b),那么交换后会产生2的贡献

    3、(h_a>h_b)

    交换后(a,b)会少一对逆序对所以ans--
    同理,对于位置在(a)前面或者(b)后面的数都没有影响
    对于处于(a,b)之间的数(i)
    (h_i=h_a)(h_i=h_b),那么交换后会减少1的贡献
    (h_a<h_i<h_b),那么交换后会减少2的贡献

    讨论一波以后就是树套树的板子了

    code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 20005;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    
    struct segment_tree{int ls,rs,num;}t[N*100];
    int n,m,h[N],o[N],len,rt[N],tot;
    long long ans;
    void modify(int &x,int l,int r,int p,int v)
    {
    	if (!x) x=++tot;t[x].num+=v;
    	if (l==r) return;
    	int mid=l+r>>1;
    	if (p<=mid) modify(t[x].ls,l,mid,p,v);
    	else modify(t[x].rs,mid+1,r,p,v);
    }
    int query(int x,int l,int r,int ql,int qr)
    {
    	if (!x||ql>qr) return 0;
    	if (l>=ql&&r<=qr) return t[x].num;
    	int mid=l+r>>1,s=0;
    	if (ql<=mid) s+=query(t[x].ls,l,mid,ql,qr);
    	if (qr>mid) s+=query(t[x].rs,mid+1,r,ql,qr);
    	return s;
    }
    int main()
    {
    	n=gi();
    	for (int i=1;i<=n;i++) o[i]=h[i]=gi();
    	sort(o+1,o+n+1);len=unique(o+1,o+n+1)-o-1;
    	for (int i=1;i<=n;i++) h[i]=lower_bound(o+1,o+len+1,h[i])-o;
    	for (int i=1;i<=n;i++)
    		for (int j=i;j<=n;j+=j&-j)
    			modify(rt[j],1,len,h[i],1);
    	for (int i=1;i<=n;i++)
    		for (int j=i-1;j;j-=j&-j)
    			ans+=query(rt[j],1,len,h[i]+1,len);
    	printf("%lld
    ",ans);
    	m=gi();
    	while (m--)
    	{
    		int a=gi(),b=gi();
    		if (a>b) swap(a,b);
    		if (h[a]<h[b])
    		{
    			++ans;
    			for (int j=b-1;j;j-=j&-j) ans+=query(rt[j],1,len,h[a],h[b])+query(rt[j],1,len,h[a]+1,h[b]-1);
    			for (int j=a;j;j-=j&-j) ans-=query(rt[j],1,len,h[a],h[b])+query(rt[j],1,len,h[a]+1,h[b]-1);
    		}
    		if (h[a]>h[b])
    		{
    			--ans;
    			for (int j=b-1;j;j-=j&-j) ans-=query(rt[j],1,len,h[b],h[a])+query(rt[j],1,len,h[b]+1,h[a]-1);
    			for (int j=a;j;j-=j&-j) ans+=query(rt[j],1,len,h[b],h[a])+query(rt[j],1,len,h[b]+1,h[a]-1);
    		}
    		for (int j=a;j<=n;j+=j&-j) modify(rt[j],1,len,h[a],-1),modify(rt[j],1,len,h[b],1);
    		for (int j=b;j<=n;j+=j&-j) modify(rt[j],1,len,h[b],-1),modify(rt[j],1,len,h[a],1);
    		swap(h[a],h[b]);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    ExecuteScalar requires the command to have a transaction when the connection assigned to the command is in a pending
    如何从vss中分离程序
    String or binary data would be truncated
    the pop3 service failed to retrieve authentication type and cannot continue
    The POP3 service failed to start because
    IIS Error he system cannot find the file specified _找不到页面
    pku2575Jolly Jumpers
    pku2940Wine Trading in Gergovia
    pku3219二项式系数
    pku1029false coin
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8320455.html
Copyright © 2011-2022 走看看