「杂题乱刷」CF1934D2

感觉 D2 比 D1 简单 /kx /kx /kx

链接

算法一

发现一个数 \(x\)\(2^k(0 \le k)\) 时一定无法拆分。

此时直接分讨即可。

算法二

发现一个数 \(x\) 满足化为二进制下数位和为 \(2\),可以拆成两个 \(2\) 的非负整数次幂的数。

此时直接分讨即可。

算法三

为方便读者理解,下文中使用 \(f(x)\) 表示 \(x\) 在二进制下的数位和。

分讨一个可拆分的数 \(x\)

  • \(x \bmod 2 = 0\),则有 \(f(p1) \bmod 2 \neq f(p2) \bmod 2\),此时后手可选择先手拆分后的数位和为偶数的二进制数,先手必败

  • \(x \bmod 2 = 1\),则有 \(f(p1) \bmod 2 = f(p2) \bmod 2\),此时先手可将此数拆分成两个数位和为奇数的二进制数,先手必胜

直接从最高位开始操作,发现每次操作这个二进制数的位数都会减少 \(1\),因此操作次数最多为 \(\log_2(n)\) 次,可以通过此题。

参考代码:

总结

此题是一道简单的构造题。

点击查看代码
/*
Tips:
你数组开小了吗?
你MLE了吗?
你觉得是贪心,是不是该想想dp?
一个小时没调出来,是不是该考虑换题?
*/
#include<bits/stdc++.h>
using namespace std;
#define map unordered_map
#define forl(i,a,b) for(register long long i=a;i<=b;i++)
#define forr(i,a,b) for(register long long i=a;i>=b;i--)
#define forll(i,a,b,c) for(register long long i=a;i<=b;i+=c)
#define forrr(i,a,b,c) for(register long long i=a;i>=b;i-=c)
#define lc(x) x<<1
#define rc(x) x<<1|1
#define mid ((l+r)>>1)
#define cin(x) scanf("%lld",&x)
#define cout(x) printf("%lld",x)
#define lowbit(x) x&-x
#define pb push_back
#define pf push_front
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
//#define endl '\n'
#define QwQ return 0;
#define ll long long
#define lcm(x,y) x/__gcd(x,y)*y
#define Sum(x,y) 1ll*(x+y)*(y-x+1)/2
ll t;
ll n,p1,p2;
/*ll f(ll x,ll opt)
{
	if(opt==0)
	{
		ll sum=0;
		while(x)
			x/=2,sum++;
		return 1ll<<(63-__builtin_clzll(x));
		return 1ll<<sum;
	}
	else if(opt==1)
	{
		ll sum=0,lastx=x;
		while(x)
			sum+=x%2,x/=2;
		sum=__builtin_popcountll(x);
		if(pd==1)
		{
			if(sum%2)	
				cout<<"second"<<endl;
			else 
				cout<<"first"<<endl;
		}
		if(sum%2==0 && pd)
			cout<<f(lastx,0)<<' '<<(f(lastx,0)^lastx)<<endl;
		pd=0;
		return __builtin_popcountll(x)&1;
		return sum%2;	
	}
	else
	{
		ll p1,p2;
		cin>>p1>>p2;
		if(p1<=0 && p2<=0)
			return 0;
		if(f(p1,1))
			cout<<f(p2,0)<<' '<<(p2^f(p2,0))<<endl;
		else
			cout<<f(p1,0)<<' '<<(p1^f(p1,0))<<endl;
		return 1;
	}
}*/
ll f(ll opt,ll x){
	if(!opt)
		return __builtin_popcountll(x)%2;
	else
		return 1ll<<(63-__builtin_clzll(x));
}
void solve()
{
/*	pd=1;
	cin>>n;
	f(n,1);
	forl(i,1,1e18)
		if(!f(0,2))
			break;*/
    cin>>n;
    cout<<(f(0,n)?"second":"first")<<endl;
    if(!f(0,n)) 
		cout<<f(1,n)<<' '<<(n^f(1,n))<<endl;
    forl(i,1,1e18)
	{
        cin>>p1>>p2; 
        if(p1<=0 && p2<=0)
        	return ;
        if(f(0,p1)) 
			cout<<f(1,p2)<<' '<<(p2^f(1,p2))<<endl;
        else 
			cout<<f(1,p1)<<' '<<(p1^f(1,p1))<<endl;
    }
}
int main()
{
//	IOS;
	t=1;
	cin>>t;
	while(t--)
		solve();
    /******************/
	/*while(L<q[i].l) */
	/*    del(a[L++]);*/
	/*while(L>q[i].l) */
	/*    add(a[--L]);*/
	/*while(R<q[i].r) */
	/*	  add(a[++R]);*/
	/*while(R>q[i].r) */
	/*    del(a[R--]);*/
    /******************/
	QwQ;
}

posted @ 2024-03-03 02:08  wangmarui  阅读(4)  评论(0编辑  收藏  举报