codeforces原题连接
大佬题解html
每一个人每次必定拿走奇数( 2 k − 1 2^k-1 2k−1)个节点,若是先手必胜不难发现两人轮流拿最终必定拿奇数次(每次奇数个节点)说明一共有奇数个节点,若是先手必败说明最终两人共拿偶数次说明有偶数个节点,所以能够根据奇偶性判断输赢。ios
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=50010; const ll mod=998244353; int n; int main() { IO; int T=1; cin>>T; while(T--) { cin>>n; for(int i=1;i<n;i++) { int a,b; cin>>a>>b; } if(n&1) cout<<"Alice\n"; else cout<<"Bob\n"; } return 0; }
模拟一下就便可。web
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=50010; const ll mod=998244353; int main() { IO; int T=1; cin>>T; while(T--) { int k;ll x; cin>>k>>x; ll base=1,s=0; while(s<x) { base=base*k; s+=base; } x-=s-base; base/=k; vector<int> ans; while(x>0&&base) { int r=(x+base-1)/base; ans.push_back(r+9-k); x-=(r-1)*base; base/=k; } for(auto t:ans) cout<<t; cout<<'\n'; } return 0; }
原本想着构造一条链,不过发现 k k k有点大搞不了,因而。。就没有因而了
参考上述题解发现本身仍是对递归不熟练。数组
若是当前节点的方案数为偶数,那么咱们构造两个方案数分别为 2 , n 2 2,\frac n 2 2,2n 的子节点;若是是奇数就构造两个方案数分别为
2 , n 2 2,\frac n 2 2,2n 的子节点,而且根节点单独做为一种方案,递归终点是 k ≤ 2 k≤2 k≤2 的时候,咱们只须要建一条链便可。markdown
当父节点的权值等于孩子节点的权值和的时候,父节点便可单独称为一种方案,若是大于就不能单独称为一种方案。svg
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=50010; const ll mod=998244353; int k,cnt; int fa[N],c[N]; int dfs(int k,int p) { int now=++cnt; fa[now]=p; if(k<=2) { fa[++cnt]=now; c[cnt]=1; c[now]=3-k; return 1; } c[now]=dfs(k/2,now)+dfs(2,now)+(k%2==0); return c[now]-(k%2==0); } int main() { IO; int T=1; //cin>>T; while(T--) { cin>>k; dfs(k,0); cout<<cnt<<'\n'; for(int i=2;i<=cnt;i++) cout<<fa[i]<<' '; cout<<'\n'; for(int i=1;i<=cnt;i++) cout<<c[i]<<' '; cout<<'\n'; } return 0; }
大佬题解
直接贴贴大佬题解的图片吧真的很是妙
spa
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=5010; const ll mod=998244353; int a[N],n; bool check(int x) { int cnt0=0,cnt1=0; for(int i=1;i<=n;i++) cnt0+=a[i]<x,cnt1+=a[i]>x; if(cnt0==cnt1) return 1; else if(cnt0<cnt1) { int cnt=0; for(int i=1;i<=n;i++) { if(a[i]>x) cnt++; else if(a[i]==x) cnt=0;//最后消x else cnt=max(cnt-1,0); if(cnt==3) { cnt1-=2,cnt=1; if(cnt0==cnt1) return 1; } } } else { int cnt=0; for(int i=1;i<=n;i++) { if(a[i]<x) cnt++; else if(a[i]==x) cnt=0;//最后消x else cnt=max(cnt-1,0); if(cnt==3) { cnt0-=2,cnt=1; if(cnt0==cnt1) return 1; } } } return 0; } int main() { IO; int T=1; cin>>T; while(T--) { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) { if(check(a[i])) cout<<1; else cout<<0; } cout<<'\n'; } return 0; }
居然还有点卡常,少了几个%就A了。
为了补这个题重学数位dp,而后发现基本的数位dpcode
// 2652 ms #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=5010; const ll mod=1e9+7; int a[N]; char l[N],r[N]; int m; int f[N][65][65][2]; int ten[N]; int dfs(int pos,int s,int cur,bool limit) { if(!pos) return cur==0; if(f[pos][s][cur][limit]!=-1) return f[pos][s][cur][limit]; int v=limit?a[pos]:9; ll res=0; for(int i=0;i<=v;i++) res+=dfs(pos-1,(s+i)%m,((cur+s*i-i*ten[pos-1])%m+m)%m,limit&&i==v); res=(res%mod+mod)%mod; return f[pos][s][cur][limit]=res; } int solve(char s[]) { int cnt=strlen(s); // 初始化记忆化数组 for(int i=1;i<=cnt;i++) for(int j=0;j<m;j++) for(int k=0;k<m;k++) f[i][j][k][0]=f[i][j][k][1]=-1; for(int i=1;i<=cnt;i++) a[i]=s[cnt-i]-'0'; return dfs(cnt,0,0,1); } int main() { IO; int T=1; cin>>T; while(T--) { cin>>l+1>>r+1; cin>>m; ten[0]=1; for(int i=1;i<=5000;i++) ten[i]=ten[i-1]*10%m; // [l,r] 差分-> [0,r]-[0,l-1] 首先让l-1 for(int i=strlen(l+1);i;i--) { if(l[i]>'0') { l[i]--; break; } else l[i]='9'; } cout<<((solve(r+1)-solve(l+1))%mod+mod)%mod<<'\n'; } return 0; }
最近做业巨难,信号+数电,感受老师上课疯狂划水,真就自学???
并且最近题解质量真的差,没时间打markdown不想打
要加油哦~xml