Atcoder Beginner Contest 380 (D~G)
D.Strange Mirroring
题意:
给定一个只含有大小写字母的字符串
现在对这个字符串操作无数次:
- 对于
的每个字符,若是大写字母就改为对应的小写字母,否则改成对应的大写字母,形成一个新的字符串 。 - 将
和 首尾连接,形成新的 。
现在给定
题解:
下面所有的序号从0开始
结论:
对于第
简单证明(?):
我们发现每一次操作实际上是所有的序号在二进制下向高位拓展了一位,前半序号这一位为
所以只需要找到
关于
https://zhuanlan.zhihu.com/p/385807077
代码:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
string s;
cin>>s;
int q;
cin>>q;
int len=s.length();
string t=s;
for(int i=0;i<s.length();i++)
{
if(s[i]>='a'&&s[i]<='z') t[i]=(char)(s[i]-'a'+'A');
else if(s[i]>='A'&&s[i]<='Z')t[i]=(char)(s[i]-'A'+'a');
}
s=' '+s;
t=' '+t;
while(q--)
{
int k;
cin>>k;
int which;
if(k%len==0) which=k/len;
else which=k/len+1;
which--;
int pos=k%len;
if(pos==0) pos=len;
int much=__builtin_popcountll(which);
much%=2;
if(!much) cout<<s[pos]<<' ';
else cout<<t[pos]<<' ';
}
return 0;
}
E.1D Bucket Tool
题意:
给出编号从
题解:
考虑并查集,我们只需要维护对于某一个并查集,其
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=5e5+10;
int fa[maxn],sz[maxn];
int num[maxn],col[maxn];
int Left[maxn],Right[maxn];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void hb(int x,int y)
{
int fa1=find(x);
int fa2=find(y);
if(fa1==fa2) return ;
fa[fa2]=fa1;
sz[fa1]+=sz[fa2];
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++)
{
fa[i]=col[i]=i,sz[i]=num[i]=1;
Left[fa[i]]=i;
Right[fa[i]]=i;
}
while(q--)
{
int type;
cin>>type;
if(type==1)
{
int x,c;
cin>>x>>c;
int father=find(x);
int color=col[father];
num[color]-=sz[father];
num[c]+=sz[father];
col[father]=c;
if(Left[father]-1>=1&&col[find(Left[father]-1)]==c)
{
int new_left=Left[find(Left[father]-1)];
hb(father,Left[father]-1);
Left[father]=new_left;
}
if(Right[father]+1<=n&&col[find(Right[father]+1)]==c)
{
int new_right=Right[find(Right[father]+1)];
hb(father,Right[father]+1);
Right[father]=new_right;
}
}
else
{
int c;
cin>>c;
cout<<num[c]<<endl;
}
}
return 0;
}
F.Exchange Game
题意:
初始时
- 轮到某个玩家的回合时,该玩家从手中打出一张牌(记为
)放置在桌子上,并允许在桌子上拿不超过一张小于 牌。 - 当一个玩家不能进行上述操作时,对方获胜,游戏结束。
若
题解:
令
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1600000;
int mi[20],val[20];
int n,m,l;
int dp[maxn][3];//dp[i][1/2]代表状态为i时,1/2先手是否会win
int dfs(int s,int x)
{
if(dp[s][x]) return dp[s][x];
vector<int>mine,all;
for(int i=0;i<n+m+l;i++)
{
int which=s/mi[i]%3;
if(which==x) mine.push_back(i);
if(which==0) all.push_back(i);
}
if(mine.size()==0)
{
if(x==1) dp[s][x]=-1;
else dp[s][x]=1;
return dp[s][x];
}
for(auto it1:mine)
{
int s_new=s-x*mi[it1];
dp[s_new][(x==1?2:1)]=dfs(s_new,(x==1?2:1));
if((dp[s_new][x==1?2:1]==1&&x==1)||(dp[s_new][x==1?2:1]==-1&&x==2)) return dp[s][x]=dp[s_new][x==1?2:1];
for(auto it2:all)
{
if(val[it1]>val[it2])
{
int new_s=s;
new_s-=x*mi[it1];
new_s+=x*mi[it2];
dp[new_s][(x==1?2:1)]=dfs(new_s,(x==1?2:1));
if((dp[new_s][x==1?2:1]==1&&x==1)||(dp[new_s][x==1?2:1]==-1&&x==2)) return dp[s][x]=dp[new_s][x==1?2:1];
}
}
}
return dp[s][x]=(x==1?-1:1);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
mi[0]=1;
for(int i=1;i<=15;i++) mi[i]=mi[i-1]*3;
cin>>n>>m>>l;
for(int i=0;i<n+m+l;i++) cin>>val[i];
int s0=0;
for(int i=0;i<n;i++) s0+=mi[i]*1;
for(int i=n;i<n+m;i++) s0+=mi[i]*2;
dfs(s0,1);
if(dp[s0][1]==1) cout<<"Takahashi"<<endl;
else if(dp[s0][1]==-1) cout<<"Aoki"<<endl;
return 0;
}
G.Another Shuffle Window
题意:
给定一个排列
请计算经过以下操作后,排列
- 首先,从
到 的整数中随机均匀地选择一个整数 ; - 然后,将子数组
进行随机均匀打乱。
题解:
先给出结论,对于长度为
证明:
对于长度为
那么我们现在只需要求出长度为
代码:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int mod=998244353;
const int maxn=2e5+10;
int tree[maxn],p[maxn],n,k;
int fast_pow(int a,int n,int mod)
{
int ans=1;
a%=mod;
while(n)
{
if(n&1) ans=(ans*a)%mod;
a=(a*a)%mod;
n>>=1;
}
return ans;
}
int inv(int a,int mod)
{
return fast_pow(a,mod-2,mod);
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int k)
{
while(x<=n)
{
tree[x]+=k;
x+=lowbit(x);
}
}
int query(int x)
{
int ans=0;
while(x)
{
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>p[i];
int sum=0;
for(int i=n;i>=1;i--)
{
sum+=query(p[i]);
add(p[i],1);
}
memset(tree,0,sizeof(tree));
int now=0;
for(int i=k;i>=1;i--)
{
now+=query(p[i]);
add(p[i],1);
}
int ans=sum-now;
for(int i=1;i<=n-k;i++)
{
add(p[i],-1);
now-=query(p[i]);
now+=query(n)-query(p[i+k]);
add(p[i+k],1);
ans=(ans+sum-now)%mod;
}
cout<<(ans*inv(n-k+1,mod)+k*(k-1)%mod*inv(4,mod))%mod<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现