zoukankan      html  css  js  c++  java
  • CodeForces

    https://codeforces.com/problemset/problem/1417/E

    正解:

    从二进制最高位开始算,不断分开分开就是答案了。

    每一位存下来按照01分开,贪心做事情,具体看代码吧,挺简单

    #include<iostream>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int maxn = 3e5+11;
    vector<int>chal;
    
    ll dp[100][10];
    int list[maxn];
    
    ll ans = 0;
    
    int dfs(vector<int>ins ,int dep){
    	if(dep < 0 ) return 0;
    	if(ins.size() == 0) return 0;
    	vector<int>cns;
    	
    	int cnt1=0,cnt0=0;
    	for(int i=ins.size()-1;i>=0;i--){
    		int x = (ins[i] >> dep)&1;
    		if(x == 1){
    			cnt1++;
    			dp[dep][1] += cnt0;
    		}
    		else{
    			cnt0++;
    			dp[dep][0] += cnt1;
    		}
    	}
    	
    	for(int i = 0;i<ins.size();i++){
    		int x = (ins[i] >> dep)&1;
    		if(x == 0){
    			cns.push_back(ins[i]);
    		}
    	}
    	dfs(cns,dep-1);
    	
    	cns.clear();
    	for(int i = 0;i<ins.size();i++){
    		int x = (ins[i] >> dep)&1;
    		if(x == 1){
    			cns.push_back(ins[i]);
    		}
    	}
    	dfs(cns,dep-1);
    	cns.clear();
    }
    
    
    int main(){
    	int n;
    	scanf("%d",&n);
    	
    	for(int i=0;i<n;i++){
    		int x;
    		scanf("%d",&x);
    		chal.push_back(x);
    	}
    	
    	dfs(chal,30);
    	ll cns = 0;
    	ll ans =0 ;
    	for(int i=30;i>=0;i--){
    		if(dp[i][0] < dp[i][1]){
    			cns += (1<<i);
    		}
    		ans += min(dp[i][0],dp[i][1]);
    	}
    	printf("%lld %lld",ans,cns);
    	return 0;
    }
    

      

    还有一种做法是我第一次写的时候盲猜的,利用线段树动态开点暴力算异或对是不是变多了,。。。结果给T了,如果n是1e5说不定可以呢。。。

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn = 3e5+1111;
    typedef long long ll;
    
    struct Node{
    	int l,r,ans;
    }tree[maxn*40];
    
    
    int list[maxn];
    int cnt = 2;
    int update(int & node,int be,int en,int i,int val){
    	if(node == 0) node = ++cnt;
    	int mid = be + en >> 1;
    	if(be == en ){
    		tree[node].ans += val;
    		return 0;
    	}
    	if(i <= mid) update(tree[node].l,be,mid,i,val);
    	else update(tree[node].r,mid+1,en,i,val);
    	int l = tree[node].l;
    	int r = tree[node].r;
    	tree[node].ans = tree[l].ans + tree[r].ans;
    }
    int ask(int node,int be,int en,int LL,int RR){
    	if(node == 0) return 0;
    	int mid = be + en >> 1;
    	if( LL <= be && en <= RR){
    		return tree[node].ans;
    	}
    	int val1 = 0,val2 = 0;
    	if(LL <= mid) val1 = ask(tree[node].l,be,mid,LL,RR);
    	if(RR > mid) val2 = ask(tree[node].r,mid+1,en,LL,RR);
    	return val1 + val2;
    }
    int init(){
    	for(int i=0;i<=cnt;i++){
    		tree[i].l = tree[i].r = tree[i].ans = 0;
    	}
    	cnt = 2;
    	return 0;
    }
    
    int main(){
    	int root = 1;
    	int n;
    	scanf("%d",&n);
    	
    	for(int i=0;i<n;i++){
    		scanf("%d",&list[i]);
    	}
    	cnt = 2;
    	ll ans = 1e17;
    	
    	int nn = 1e9+11;
    	ll cns = 0;
    	
    	for(int i = 30;i>=0;i--){
    		int x = 1<<i;
    		ll a = 0;
    		ll b = 0;
    		for(int j=n-1;j>=0;j--){
    			if(list[j] == 0){
    				update(root,0,nn,0,1); 
    				continue;
    			}
    			a += ask(root,0,nn,0,list[j]-1);
    			update(root,0,nn,list[j],1);
    		}
    		for(int j=n-1;j>=0;j--){
    			update(root,0,nn,list[j],-1);
    		}
    		
    		for(int j=n-1;j>=0;j--){
    			list[j] ^= x;
    			if(list[j] == 0){
    				update(root,0,nn,0,1); 
    				continue;
    			}
    			b += ask(root,0,nn,0,list[j]-1);
    			update(root,0,nn,list[j],1);
    		}
    		
    		for(int j=n-1;j>=0;j--){
    			update(root,0,nn,list[j],-1);
    		}
    		if(a <= b){
    			for(int j=0;j<n;j++){
    				list[j] ^= x;
    			}
    		}
    		else{
    			cns += x;
    		}
    		
    		a = min(a,b);
    		ans = min(a,ans);
    	}
    	
    
    	printf("%lld %lld
    ",ans,cns);
    	return 0;
    } 
    
    
    
    ?
    

      

  • 相关阅读:
    Hubble.net 持久化方面3个重大改进
    并行排序算法
    var_dump打印变量的相关信息
    out of socket memory相关tcp参数
    lsof命令使用示例
    tcp_max_orphans
    print_r打印关于变量的易于理解的信息
    linux动态加载库
    pfiles命令
    var_export输出或返回一个变量的字符串表示
  • 原文地址:https://www.cnblogs.com/lesning/p/13932445.html
Copyright © 2011-2022 走看看