比赛链接:https://codeforces.com/contest/1327
A. Sum of Odd Integers
上来几分钟才加载出来,切A又切不动555
一波分析发现和最小的 \(k\) 个数一定是 \(1,3,5,...,(2k-1)\),如果 \(n\) 小于它们之和,就不行
还有如果它们之和的奇偶性和 \(n\) 不一样也不行
#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=[]{ios::sync_with_stdio(0); cin.tie(0); return 0;}();
typedef long long ll;
const int N=200010;
#define int ll
int t,n,j;
signed main(){
cin>>t;
while(t--){
cin>>n>>j;
cout<<(j*(1+2*j-1)/2<=n && (j*(1+2*j-1)/2+n)%2==0?"YES":"NO")<<endl;
}
return 0;
}
B. Princesses and Princes
题目真的长到自闭
刚开始匹配一波,然后找两个未被匹配的输出就行了
找不到当然直接OPTIMAL
辣鸡代码警告
#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=[]{ios::sync_with_stdio(0); cin.tie(0); return 0;}();
typedef long long ll;
const int N=200010;
#define int ll
int t,n,j;
bool f[N],g[N]; //g表示公主被匹配,f表示王子被匹配
vector<int> a[N];
void find(){
cout<<"IMPROVE"<<endl;
repeat(i,0,n)if(!g[i]){cout<<i+1; break;}
repeat(i,0,n)if(!f[i]){cout<<' '<<i+1<<endl; break;}
}
signed main(){
cin>>t;
while(t--){
cin>>n;
repeat(i,0,n)a[i].clear();
fill(f,f+n,0);
fill(g,g+n,0);
int cnt=0;
repeat(i,0,n){
int m,x; cin>>m;
repeat(j,0,m)cin>>x,x--,a[i].push_back(x);
for(auto p:a[i]){
if(!f[p]){
f[p]=1;
g[i]=1;
cnt++;
break;
}
}
}
if(cnt==n)cout<<"OPTIMAL"<<endl;
else find();
}
return 0;
}
C. Game with Chips
emmm直接输入 \(n,m\) 就好了,后面懒得输入,输出可以遍历所有点的走法
我还犹豫好久
#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=[]{ios::sync_with_stdio(0); cin.tie(0); return 0;}();
typedef long long ll;
const int N=200010;
#define int ll
int t,n,m;
signed main(){
cin>>n>>m;
string s;
s+=string(m-1,'L');
s+=string(n-1,'U');
repeat(i,0,n){
if(i%2==0)s+=string(m-1,'R');
else s+=string(m-1,'L');
if(i!=n-1)s+='D';
}
cout<<s.length()<<endl;
cout<<s<<endl;
return 0;
}
D. Infinite Path
会循环置换应该就没问题
首先有一个不知道叫什么名字的定理,任意一个置换都可以拆成若干个不相交的循环置换
什么?循环置换是什么?没做专题13暴露了吧(huge fog)
循环置换什么的可以找一些博客看一下,比如最简单易得的oi-wiki:https://oi-wiki.org/math/permutation-group/
因此接下来我默认大家会了这个定理:
我们先找到一个循环置换 \(P\)(所有循环置换都要执行一遍接下来的操作),长度记为 \(len\),事实上 \(P^k\) 其实也能进一步拆成多个小循环置换,而且恰好是 \(\gcd(k,len)\) 个,当然,每个小循环置换的长度就是 \(\dfrac {len} {\gcd(k,len)}\)
而且有结论 \(\gcd(k,len)\) 相等的两个 \(k\) 拆出来的小循环置换是一模一样的(可以 \(len=6,k=1...6\) 玩一玩)
所以我们只要让 \(k\) 遍历所有 \(len\) 的约数(这样的话每个 \(\gcd(k,len)\) 都不相同),每次把小循环置换拿出来问它是不是只有一种颜色,如果是就更新答案
最终复杂度是 \(O(n\sqrt n)\)
辣鸡代码警告
#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=[]{ios::sync_with_stdio(0); cin.tie(0); return 0;}();
typedef long long ll;
const int N=200010;
#define int ll
int t,n,m,ans;
int a[N],co[N],vis[N];
vector<int> rec,v;
bool work2(int s,int step){
int n=rec.size();
int p=s,nxt=(p+step)%n;
while(nxt!=s){
if(rec[p]!=rec[nxt])return 0;
p=nxt,nxt=(p+step)%n;
}
return 1;
}
void work(){
int n=rec.size();
for(int i=1;i<n;i=n/(n/(i+1))) //这花里胡哨的其实是求n的所有约数
if(n%i==0){
repeat(j,0,i){
if(ans<=i)return;
if(work2(j,i)){
ans=min(ans,i);
return;
}
}
}
int i=n;
repeat(j,0,i){
if(ans<=i)return;
if(work2(j,i)){
ans=min(ans,i);
return;
}
}
}
signed main(){
cin>>t;
while(t--){
cin>>n;
fill(vis,vis+n+1,0);
repeat(i,1,n+1)cin>>a[i];
repeat(i,1,n+1)cin>>co[i];
ans=1e9;
repeat(i,1,n+1)if(!vis[i]){
int p=i;
rec.clear();
while(!vis[p]){
rec.push_back(co[p]);
vis[p]=co[p];
p=a[p];
}
work();
}
cout<<ans<<endl;
}
return 0;
}
E. Count The Blocks
又是喜(sang)闻(xin)乐(bing)见(kuang)的计数题
对每一个大小为 \(i\) 的快,我们发现如果把它放中间,它的相邻两个数字都有 \(9\) 个取值(除了和块一样的取值),剩下的 \(n-i-2\) 块都有 \(10\) 个取值
如果把它放边界上,就只有一个数字与它相邻,因此稍作修改
最后for一遍就可以了
#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=[]{ios::sync_with_stdio(0); cin.tie(0); return 0;}();
typedef long long ll;
const int N=200010;
const int mod=(0?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;} ll getinv(ll v,ll m=mod){return qpow(v,m-2,m);}
#define int ll
int t,n,m;
signed main(){
cin>>n;
repeat(i,1,n+1){
ll ans=0;
if(n-i>=2){
ans+=mul(81*(n-i-1),qpow(10,n-i-2));
ans+=mul(9*2,qpow(10,n-i-1));
ans%=mod;
}
else if(n-i==1){
ans+=mul(9*2,qpow(10,n-i-1));
ans%=mod;
}
else ans=1;
ans=mul(ans,10);
cout<<ans<<' ';
}
return 0;
}