zoukankan      html  css  js  c++  java
  • CF1188D Make Equal

    题意

    给出(n)个数(a_i),每次操作可以给一个数加上(2^k)。问最少需要多少次操作来使得该数组的每个元素都相等。

    (nle 10^5,a_i le 10^{17})

    传送门

    思路

    即求数组(b),使得(a_i+b_i)都相同且(sum ext{bitcount}(b_i))最小

    排序差分,最大的数改变(b_n),则(b_i=b_n+(a_n-a_i)),求(b_n)使得,(sum ext{bitcount}(b_n+(a_n-a_i)))最小

    然后就变成了一道双倍经验题CF778E

    很容易想到记录后一位的进位情况,然后从低位到高位转移,(dp[i][j])表示当前考虑到第(i)位,(j)中为(1)的数后一位有进位,枚举(b_n)当前位上是(0)还是(1),但是这样子状态数是(2^n),思考有没有优化方法。

    越大的数越容易进位,在只考虑后面位的时候,也就是按(0 ext{~} i)位从大到小排序(只有两个数的基数排序),前面的越容易进位。也就是一个前缀,所以只要将(O(2^n))枚举变成(O(n))枚举前缀长度,从小到大依次改变代价和进位数量就可以了。

    #include <bits/stdc++.h>
    typedef long long ll;
    const int N=100005,INF=N*1000;
    int rank[N],dp[70][N],tmp[N],n;
    ll a[N],p[70];
    void Sort(int x){
    	int k=0;
    	for (int i=1;i<=n;i++) 
    		if (a[rank[i]]&p[x]) tmp[++k]=rank[i];
    	for (int i=1;i<=n;i++) 
    		if ((a[rank[i]]&p[x])==0) tmp[++k]=rank[i];	
    	for (int i=1;i<=n;i++) rank[i]=tmp[i];
    }
    void solve(int w,int x){
    	int cnt=0,sum=0;
    	for (int i=1;i<=n;i++){
    		int t=(a[i]&p[w])>0;
    		if (t+x==2) cnt++;
    		if (t+x==1) sum++;
    	}
    	if (dp[w][0]<INF) dp[w+1][cnt]=std::min(dp[w+1][cnt],dp[w][0]+sum);
    	for (int i=1;i<=n;i++){
    		int t=(a[rank[i]]&p[w])>0;
    		if ((t+x+1)%2) sum++;
    		if (t+x+1==2) cnt++,sum--;
    		if (dp[w][i]<INF) dp[w+1][cnt]=std::min(dp[w+1][cnt],dp[w][i]+sum);
    	}
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
    	std::sort(a+1,a+n+1);
    	ll x=a[n];int w=0;
    	while (x) x/=2,w++;
    	p[0]=1;
    	for (int i=1;i<=w;i++) p[i]=p[i-1]<<1;
    	memset(dp,0x3f,sizeof(dp));
    	dp[0][0]=0;
    	for (int i=1;i<=n;i++) rank[i]=i;
    	for (int i=1;i<=w+1;i++){
    		for (int j=0;j<=1;j++)
    			solve(i-1,j);
    		Sort(i-1);
    	}
    	int ans=INF;
    	printf("%d
    ",dp[w+1][0]);
    }
    

    后记

    继咕咕咕很久以及起始考爆炸之后的浑浑噩噩

  • 相关阅读:
    浅谈过载保护
    HDU 4893 Wow! Such Sequence!(线段树)
    汇编学习-堆栈与子程序
    HDU1863_畅通project【Prim】【并查集】
    mybatis批量插入oracle大量数据记录性能问题解决
    iOS开发自己定义键盘回车键Return Key
    ubuntu server 14.04 vncserver with gnome
    MYSQL: Cannot delete or update a parent row: a foreign key constraint fails
    windows Compiler toolchain env
    C基本语句测试
  • 原文地址:https://www.cnblogs.com/flyfeather6/p/12710994.html
Copyright © 2011-2022 走看看