A Matrix Equation +++
B Number Game ???
C Stone Game ---
D Fight against involution ---
E Tree Transform ???
F Gcd Product ???
G Xor Transformation ---
H Path Killer ???
I Random Walk On Tree ---
J Tree Constructer !!!
构造题 难想啊
因为树是天然的二分图
我们先黑白染色 个数少的为基准(原因后面讲)
然后排列成二分图的形式
以左侧为基准(假设左侧个数少)
首先左侧的点自己不能连边 所以低两位为10
右侧同理 但是右侧得和左侧连边 所以右侧低两位是01
左侧的点初始值设为 2^60-1-1
右侧的点初始值设为 1
然后依次考虑左侧的点 从第3位(由低到高)开始 去掉这一位
在与他相邻的点中加上这一位 这样就构成了锁和钥匙的形式
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
vector<int>to[N];
typedef long long ll;
const ll inf = (1ll<<60)-1ll;
ll val[N];
#define pb push_back
vector<int>f[2];
void dfs(int u,int fa,int d){
f[d].pb(u);
for(auto v:to[u]){
if(v==fa) continue;
dfs(v,u,d^1);
}
}
int main(){
int n;
scanf("%d",&n);
for(int i = 1; i < n; i++){
int x,y;
scanf("%d%d",&x,&y);
to[x].pb(y);
to[y].pb(x);
}
dfs(1,0,0);
if((int)f[0].size()>(int)f[1].size())
swap(f[0],f[1]);
for(auto v:f[0]){
val[v]=inf-1ll;
}
for(auto v:f[1]){
val[v]=1;
}
ll now=2ll;
for(auto v:f[0]){
val[v]^=(1ll<<now);
for(auto k:to[v]){
val[k]|=(1ll<<now);
}
now++;
}
for(int i = 1; i <= n; i++) printf("%lld%c",val[i],i==n?'\n':' ');
return 0;
}
K Kth Query ???
L Bit Sequence !!!
一道数位dp,首先m的大小并不是很大,所以数位dp到最后一位的值可以直接遍历m,现在就是要存哪些状态了,100是小于2的七次方也就是128的,所以加上一个小于m的值最多会影响第八位小后的那些连续的1,我们把这些连续的1的奇偶存起来,如果是奇数的话加上那个小于m的值进位后还是奇数,不影响,但是偶数的话会变成奇数,改变了奇偶性,还有就是后七位要存起来,第八位以后的一的个数也要存起来,具体看代码
pos是位置,h是后七位的值,g是第八位之后的连续1的个数,c是第八位之后的1的奇偶性,flag是限制
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
ll dp[70][128][2][2][2];
ll w[150],a[150];
int m;
ll x;
ll get(int h,int g,int c){
int ans=1;
if(g==1)g=0;
else g=1;
for(int i=0;i<m;i++){
if(i+h>=128){
if((__builtin_parity((i+h)%128)^c^g)!=a[i])ans=0;
}
else{
if((__builtin_parity((i+h)%128)^c)!=a[i])ans=0;
}
}
return ans;
}
ll dfs(int pos,int h,int g,int c,int flag){
if(pos==0){
return get(h,g,c);
}
if(dp[pos][h][g][c][flag]!=-1)return dp[pos][h][g][c][flag];
int maxn=1;
if(flag==1)maxn=w[pos];
ll ans=0;
for(int i=0;i<=maxn;i++){
if(pos>=8){
if(i==1){
ans=ans+dfs(pos-1,h,g^1,c^i,flag&(i==maxn));
}
else{
ans=ans+dfs(pos-1,h,0,c^i,flag&(i==maxn));
}
}
else{
ans=ans+dfs(pos-1,2*h+i,g,c,flag&(i==maxn));
}
}
dp[pos][h][g][c][flag]=ans;
return ans;
}
ll solve(){
int cnt=0;
while(x!=0){
w[++cnt]=x%2;
x=x/2;
}
return dfs(cnt,0,0,0,1);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(dp,-1,sizeof(dp));
scanf("%d %lld",&m,&x);
for(int i=0;i<m;i++){
scanf("%d",&a[i]);
}
printf("%lld\n",solve());
}
}