1:
$\oplus$ 表示异或,$\land$ 表示与。
下面是本文需要用到的几个结论:
加法操作和异或操作有一个共同的作用:改变数字的奇偶性,并且对奇偶性的改变是同步的
奇数+奇数=偶数,奇数^奇数=偶数
奇数+偶数=奇数,奇数^偶数=奇数
偶数+偶数=偶数,偶数^偶数=偶数
1. 一个序列的异或和一定小于等于数值和。
证明:异或的本质是二进制下的不进位加法,相比起进位的普通加法,所得的结果当然会较小。当然,在进位不会发生,也就是加数之间没有相同的位(与值为 $0$)时,两者是等价的。
2. 一个序列的数值和和异或和奇偶性相同。
证明:首先继续分析结论 1,得到一个等式:
$$ a+b = (a \oplus b) + 2(a \land b)$$
$$ (a+b) - (a \oplus b) = 2(a \land b) $$
$2(a \land b)$ 是二进制下手动进位(找到相同位,左移一位)。
因为 $a \land b$ 一定是整数,所以 $(a+b)-(a \oplus b)$ 一定是 $2$ 的倍数(偶数)。当然,这个只是两个数的情况,三个数或更多依次分析即可。
那么,当 $u \not\equiv v \pmod{2}$,或者 $u > v$ 时,答案就是 $-1$ 了。
设两个数为 $n$ 和 $m$,我们可以把它们分为 $3$ 部分,有 $x \oplus x \oplus y = m$。对于 $x$ 和 $x$,$x \oplus x = 0$,然后 $0 \oplus y = y$,所以此时让 $y = n$ 即可。
考虑是否有长度为 $2$ 的解,注意由于上一步,我们有 $y = n$,发现,如果有 $(x + n) \oplus x = n$ 或者 $(x \oplus x) \oplus n = n$,那么有 $(x + n) \oplus x = n$ 或 $(x \oplus x) \oplus n = n$,此时答案变成 $2$。
#include<bits/stdc++.h> #define int long long using namespace std; const int N=2e5+10; signed main() { int n,m; cin>>n>>m; int u=m-n; if(u<0||m%2!=n%2) return cout<<-1<<endl,0; if(m==0) return cout<<0<<endl,0; if(n==m) return cout<<1<<endl<<n<<endl,0; int now=u/2; if(((now+n)^now)==n) cout<<2<<endl<<now<<' '<<now+n<<endl; else if(((now+now)^n)==n) cout<<2<<endl<<now*2<<' '<<n<<endl; else cout<<3<<endl<<now<<' '<<now<<' '<<n<<endl; return 0; }
2:
又是道思维题,来,让我们仔细分析:
首先规定模型: $t$ 先拿然后 $hl$ 再拿,所以有一个显然的情况:
那就是如果有一堆石头比其他所有的都多,特别多,那么 $t$ 只需要一直呆在这堆石头上就行了,$hl$ 取完所有的也不够 $t$ 自己的这一堆。
然后考虑不满足这种情况的,首先:假设一种为 $4 \ 1 \ 1 \ 1 \ 1$,那么无论 $t$ 他一开始在哪,都不会赢,因为 $t$ 先手。
如果 $t$ 在 $4$,那么 $hl$ 取 $1$,又 $t$ 先手,一定是 $t$ 先取完。如果 $t$ 放弃 $4$ 跑去取 $1$ 呢?那么就变成了 $4 \ 0 \ 1 \ 1 \ 1$,$hl$ 一直守着第一堆就可以了。
如果是 $5 \ 3 \ 1 \ 1 \ 1$,自己推一下又可以发现,无论 $t$ 先手在哪个石堆,经过两次之后,会出现 $5 \ 2 \ 0 \ 1 \ 1$,此时改 $t$ 先手,$t$ 赢。
当然,情况不一定是 $5 \ 2 \ 0 \ 1 \ 1$,但是一定会出现一个很大的堆,因为我们的最大堆和其他的值差值为奇数,也就是第奇数次该 $t$ 选,
所以当出现最大堆的时候,一定是 $t$ 选。
简单来说:
如果某一堆比其他堆加起来还要多,那么先手必胜,可以一直选这一堆。
否则,两人不可能让某一堆比其他堆加起来还要多这种情况出现,否则自己必败,所以所有石子都会被取完,直接判断奇偶性即可。
/* 又是道思维题,来,让我们仔细分析: 首先规定模型: t先拿然后hl再拿,所以有一个显然的情况: 那就是如果有一堆石头比其他所有的都多,特别多,那么t只需要一直呆在这堆石头上就行了,hl取完所有的也不够t自己的这一堆 然后考虑不满足这种情况的,首先: 假设一种为 4 1 1 1 1,那么无论t他一开始在哪,都不会赢,因为,t先手 如果t在4,那么hl取1,又t先手,一定是t先取完,如果t放弃4跑去取1呢?那么就变成了 4 0 1 1 1,hl一直守着第一堆就可以了 如果是 5 3 1 1 1,自己推一下又可以发现,无论t先手在哪个石堆,经过两次之后,会出现 5 2 0 1 1,此时改t先手,t赢 当然,情况不一定是5 2 0 1 1,但是一定会出现一个很大的堆,因为我们的最大堆和其他的值差值为奇数,也就是第奇数次该t选 所以当出现最大堆的时候,一定是t选 */ #include<bits/stdc++.h> using namespace std; const int N=2e5+10; int a[N]; void solve() { int n; cin>>n; int sum=0,maxx=-1; for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i],maxx=max(maxx,a[i]); for(int i=1;i<=n;i++) if(a[i]>sum-a[i]) return cout<<"w"<<endl,void(); if((sum-maxx*2)%2==1) return cout<<"w"<<endl,void(); cout<<"m"<<endl; } int main() { int t; cin>>t; while(t--) solve(); }
标签:奇数,int,偶数,challenger,异或,hl,become,oplus From: https://www.cnblogs.com/o-Sakurajimamai-o/p/17857676.html