zoukankan      html  css  js  c++  java
  • 【CF949E】Binary Cards

    题目

    题目链接:https://codeforces.com/problemset/problem/949/E
    给出 (n) 个需要表示的数,你需要用最少的 (2^k)(-2^k),使得能拼出所有需要表示的数。输出方案。
    (n,|a_i|leq 10^5)

    思路

    首先 (2^k)(-2^k) 中最多选一个。因为选两个 (2^k) 不如选 (2^k)(2^{k+1});选 (2^k)(-2^k) 不如选 (2^{k+1})(-2^k)
    从低位往高位依次考虑。如果这一位中存在二进制下为 (1) 的数,那么必然会选,否则必然不选。
    直接枚举所有情况跑是 (O(nA)) 的。其中 (A) 是值域。观察到处理完第 (k) 位后,剩余的所有数 (mod 2^k) 都应该为 (0)。也就是每选一个数,剩余的不同的数的数量就会减半。
    那么每次操作完后都去重一次就好了。
    时间复杂度 (O(nlog A))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100010,LG=18;
    int n,m,a[LG+1][N],b[LG+1],c[LG+1];
    
    void solve(int dep,int n,int cnt)
    {
    	if (cnt>=m || dep>LG) return;
    	if (n==1 && !a[dep][1])
    	{
    		memcpy(b,c,sizeof(b)); m=cnt;
    		return;
    	}
    	bool flag=0;
    	for (int i=1;i<=n;i++)
    		if (a[dep][i]&1) { flag=1; break; }
    	if (!flag)
    	{
    		for (int i=1;i<=n;i++)
    			a[dep+1][i]=(a[dep][i]>>1);
    		solve(dep+1,n,cnt);
    	}
    	else
    	{
    		for (int i=1;i<=n;i++)
    			a[dep+1][i]=((a[dep][i]-(a[dep][i]&1))>>1);
    		int n1=unique(a[dep+1]+1,a[dep+1]+1+n)-a[dep+1]-1;
    		c[cnt+1]=(1<<dep);
    		solve(dep+1,n1,cnt+1);
    		for (int i=1;i<=n;i++)
    			a[dep+1][i]=((a[dep][i]+(a[dep][i]&1))>>1);
    		n1=unique(a[dep+1]+1,a[dep+1]+1+n)-a[dep+1]-1;
    		c[cnt+1]=-(1<<dep);
    		solve(dep+1,n1,cnt+1);
    	}
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&a[0][i]);
    	sort(a[0]+1,a[0]+1+n);
    	n=unique(a[0]+1,a[0]+1+n)-a[0]-1;
    	m=1e9;
    	solve(0,n,0);
    	cout<<m<<"
    ";
    	for (int i=1;i<=m;i++)
    		cout<<b[i]<<" ";
    	return 0;
    }
    
  • 相关阅读:
    touchMove VS touchCancel
    svg viewbox 作用
    reactjs reactLink
    放开linux下的端口
    运算符重载函数作为类成员函数和友元函数 (转)
    MBean和MXBean 区别
    transfer-encoding
    CSRF
    vue知识拓展
    居中
  • 原文地址:https://www.cnblogs.com/stoorz/p/15390790.html
Copyright © 2011-2022 走看看