zoukankan      html  css  js  c++  java
  • [NOI Online #1 提高组]冒泡排序

    这个题很绕,记数字i前面有cns[i]个数字比他大,逆序对个数就是sigmi cns[i]

    反转k次就是让cns[i] - k (i>=1 && i <= n) 而且cns[i]不能有负数

    利用两个线段树维护一下,就是有点绕。。。。

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll ;
    
    const int maxn = 2e5+11;
    struct Node{	
    	ll ans,sum;
    }tree[4][maxn*4];
    
    int update(int id,int node,int be,int en,int i,int val){
    	int mid = be + en >> 1;
    	int l = node*2;
    	int r = node*2+1;
    	if(be == en){
    		tree[id][node].ans += val;
    		
    		if(val > 0) tree[id][node].sum += 1;
    		if(val < 0) tree[id][node].sum -= 1; 
    		return 0;
    	}
    	if(i <= mid) update(id,l,be,mid,i,val);
    	else update(id,r,mid+1,en,i,val);
    	tree[id][node].ans = tree[id][l].ans + tree[id][r].ans;
    	tree[id][node].sum = tree[id][l].sum + tree[id][r].sum;
    	return 0;
    }
    
    
    ll ask(int id,int node,int be,int en,int LL,int RR){
    	int mid = be + en >> 1;
    	int l = node*2;
    	int r = node*2+1;
    	if(LL <= be && en <= RR){
    		return tree[id][node].ans;
    	}
    	ll a = 0;
    	if(LL <= mid) a += ask(id,l,be,mid,LL,RR);
    	if(RR >  mid) a += ask(id,r,mid+1,en,LL,RR);
    	return a;
    }
    
    ll ask2(int id,int node,int be,int en,int LL,int RR){
    	int mid = be + en >> 1;
    	int l = node*2;
    	int r = node*2+1;
    	if(LL <= be && en <= RR){
    		return tree[id][node].sum;
    	}
    	ll a = 0;
    	if(LL <= mid) a += ask2(id,l,be,mid,LL,RR);
    	if(RR >  mid) a += ask2(id,r,mid+1,en,LL,RR);
    	return a;
    }
    
    int list[maxn];
    ll cns[maxn];
    
    int main(){
    	int n,m;
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&list[i]);
    		ll a = 0;
    		if(list[i] != n) a = ask(0,1,1,n,list[i]+1,n);
    		cns[list[i]] = a;
    		update(2,1,1,n,list[i],a);
    		
    		if(a != 0) update(1,1,1,n,a,a);
    		
    		update(0,1,1,n,list[i],1); 
    	}
    	
    	while(m--){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		if(x == 1){
    			if(list[y] < list[y+1]){
    				ll ans = cns[list[y]];
    				if(ans != 0) update(1,1,1,n,ans,-ans);
    				update(1,1,1,n,ans+1,ans+1);
    				
    				cns[list[y]]++;
    				update(2,1,1,n,list[y],1);
    			}
    			else{
    				ll ans = cns[list[y+1]];
    				update(1,1,1,n,ans,-ans);
    				if(ans - 1 != 0) update(1,1,1,n,ans-1,ans-1);
    				
    				cns[list[y+1]]--;
    				update(2,1,1,n,list[y+1],-1);
    			}
    			swap(list[y],list[y+1]);
    		}
    		else{
    			ll ans = 0;
    			if(y == 0){
    				ans = ask(2,1,1,n,1,n);
    			}
    			else if(y >= n){
    				ans = 0;
    			}
    			else{
    				ans = ask(2,1,1,n,1,n) - ask(1,1,1,n,1,y) - ask2(1,1,1,n,y+1,n)*y;
    //				cout<<ask(2,1,1,n,1,n)<<" "<<ask(1,1,1,n,1,y)<<" "<<ask2(1,1,1,n,y+1,n)<<endl;
    			}
    			
    			printf("%lld
    ",ans);
    		}
    	}
    	
    	
    	
    	
    	return 0;
    }
    

      

  • 相关阅读:
    Android MediaScanner 详尽分析
    你要清楚的东西
    Centos下搭建Apache+mysql+php
    Centos 安装MySQL全过程
    sdk platform tools is missing please user the sdk manager to install it
    尚书令
    文字
    ubuntu下mysql配置
    学习Android开发,配置环境,
    Sphinx全文索引安装教程
  • 原文地址:https://www.cnblogs.com/lesning/p/14010354.html
Copyright © 2011-2022 走看看