To become challenger

发布时间 2023-11-26 18:37:36作者: o-Sakurajimamai-o

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<<"T"<<endl,void();
    if((sum-maxx*2)%2==1) return cout<<"T"<<endl,void();
    cout<<"HL"<<endl;
}
int main()
{
    int t; cin>>t; while(t--) solve();
}