首页 > 其他分享 >TopCoder 15903 EllysNim

TopCoder 15903 EllysNim

时间:2023-10-13 15:22:40浏览次数:38  
标签:15903 int pos ans TopCoder now EllysNim

TopCoder 15903 EllysNim(https://vjudge.net/problem/TopCoder-15903)

\(n\)看似有点东西,实际上就只是一个贪心。。。

设\(i\)表示第\(i\)位,且\(i\)从\(0\)开始计数

那么我们肯定是让\(i\)从高位到低位枚举,若当前位的异或值为\(1\),想办法让它变成\(0\)且不会改变更高位的异或值

首先,若我们想改变第\(i\)位的异或值,那么最优的方法肯定是将一个第\(i\)位为\(0\)的数的后\(i+1\)位加成\(2^i\),选多个肯定不如选一个优,设这个数的后\(i+1\)位为\(a\),那么代价就是\(2^i-a\),这样也不会对更高的位造成影响

但我们的选择多半不只有一个\(a\),假设当前有两个数,它们都是合法的且对应的后\(i+1\)位分别为\(a\)和\(b\)(\(a<b\)),如果我们把\(a\)变成\(2^i\)花费\(2^i-a\)的代价不如将\(b\)变成\(2^i\)花费\(2^i-b\)的代价,至少仅在第\(i\)位看起来是正确的,如果在后面的操作中,我们发现其实第\(i\)位选\(a\)优于\(b\),我们也可以反悔,因为我们可以将\(a\)变成\(b\)花费\(b-a\)的代价,这样总的代价就还是\(2^i-a\),也就是相当于我们将第\(i\)位选的数字从\(b\)变成了\(a\),而且现在还有了一个可以自由支配的\(b\),那么就和我们一开始舍弃的把\(a\)变成\(2^i\),\(b\)留下的方案一样了,这样就是一个反悔贪心

然后具体的,当从\(a\)变成\(b\)的时候,就是在第\(j\)位(\(j<i\)且\(2^j\geq b\),因为\(2^j\geq b\)所以此时只看后\(j+1\)位的话\(a\)和\(b\)都不变)选到\(a\)时,即此时剩下的所有数中,\(a\)是合法且后\(j+1\)位最大的,此时\(a\)变成\(2^j\),就相当于\(a\rightarrow b\rightarrow 2^j\),若不满足这些条件,就说明反悔了答案更劣,所以不反悔

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=105;
int n;
ll b[N],xorr,now,ans=1e18,t;
bool work(int lim){
	ll s=(1ll<<lim)-1; int pos=n;
	for(int i=0;i<n;++i) if(!(b[i]>>lim&1)&&(b[i]&s)>=(b[pos]&s)) pos=i;
	if(pos==n) return false;
	now^=b[pos],t+=(1ll<<lim)-(b[pos]&s),b[pos]=1ll<<lim;
	return true;
}
class EllysNim{
	public:
		ll getMin(vector<int> a){
			n=a.size();
			for(int i=0;i<n;++i) xorr^=a[i];
			if(!xorr) return 0;
			for(int i=30;~i;--i){
				if(xorr>>(i+1)) break;
				now=xorr,t=0;
				for(int j=0;j<n;++j) b[j]=a[j];
				for(int j=i;~j;--j){
					if((now>>j&1)||i==j){
						if(!work(j)){
							t=1e18;
							break;
						}
						if(i==j&&!(now>>j&1)&&!work(j)){
							t=1e18;
							break;
						}
					}
				}
				ans=min(ans,t);
			}
			return ans;
		}
};

标签:15903,int,pos,ans,TopCoder,now,EllysNim
From: https://www.cnblogs.com/LuoyuSitfitw/p/17762189.html

相关文章

  • Topcoder 10880 - Rabbit Problemming
    \[兔子,兔子,兔子\]首先,我们考虑一只兔子可以达到的最大值\(mx_i\)和最小值\(mn_i\),这个可以很方便的求出来。并且每只兔子的取值是独立的。然后,如果一个组合能被选中,那么在这个组合内部所有的兔子都取\(mx_i\),其他的兔子都取\(mn_i\)的时候一定也能被选中。我们就钦定所有......
  • Topcoder 10880 - Functional Equation
    首先分析一下这个鬼畜的函数,我们考虑\(f(x)+2C\)\(=f(2f(x)-x+1)+C\)\(=f(2f(2f(x)-x+1)-(2f(x)-x+1)+1)\)\(=f(2(f(x)+C)-2f(x)+x-1+1)\)\(=f(x+2C)\)也就是\(f(x)=f(x\bmod2C)+2C\lfloor\dfrac{x}{2C}\rfloor\)也就是,只要决定了\(f(x)\),\(f(x+2mC)\)也就被确定了。......
  • 题解 Topcoder SRM789 FollowingNim
    题目链接题意给定\(n\)堆石子\(a_1,a_2,\cdots,a_n\)和一个集合\(S\),两名玩家轮流行动,每次可以在某堆石子中取走\(x\)个(不能不取)。特殊地,如果\(x\inS\),那么下......
  • TopCoder14563 DerangementsStrikeBack
    使用类似传统的错排公式\(D(n)=(n-1)\times(D(n-1)+D(n-2))\)的推导过程。首先,\(D_i\)整体除了一个\(n!\),代表后\(n\)个球整体相同。局面设定为求\(......