AtCoder Beginner Contest 200 F

这题的思路很清晰,和这题类似。

我们先考虑不将它重复k次,即字符串S所有的方案的和的平均数

首先,若没有?=2,那我们将每两个不同的字符的贡献看成12,由于若相邻的不同的个数为奇数时要向上取整,我们发现,此时S|S|S1一定不是同一个数,比如下面的情况

11100011000

所以,我们把|S|1看成也是相邻的即可(类似环)。

?呢?

  • ?+0/1 或 0/1+?,可以计算贡献为14

  • ?+?

    • 0+01+1贡献为0;
    • 0+11+0贡献为1。

    即,总的贡献仍为14

这样,我们计算出所有S的答案的平均数num,我们先将其乘k(重复k次),得到重复k次的平均数。而我们有2kq种方案,qS中的?的数量。所以,答案为:

num×k×2kq

注意:

|S|=1k=1时,不存在相邻的字符,我们应特判,输出0

代码:

#include<bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(v) (int)(v).size()
#define all(v) (v).begin(),(v).end()

typedef long long ll;
typedef pair<int,int> pi;

const ll mod=1000000007;
const ll inv2=500000004,inv4=250000002;
ll k,cnt,ans;
string s;

ll qpow(ll x,ll y) {
	if(y==0ll) return 1;
	ll ret=qpow(x,y>>1ll);
	ret*=ret,ret%=mod;
	if(y&1ll) ret*=x,ret%=mod;
	return ret;
}

ll calc(char x,char y) {
	if(x=='?'||y=='?') return inv4;
	if(x!=y) return inv2;
	return 0;
}

int main() {
	cin>>s>>k;
	if(sz(s)==1&&k==1) {
		puts("0");
		exit(0);
	}
	for(int i=0;i<sz(s);i++) {
		ans+=calc(s[i],s[(i+1)%sz(s)]);
		cnt+=(s[i]=='?');
		ans%=mod;
	}
	ans=ans*k%mod*qpow(2ll,cnt*k)%mod;
	cout<<ans<<endl;
	return 0;
}
posted @   Nastia  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示