专栏文章
题解:CF150B Quantity of Strings
CF150B题解参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mir0epmf
- 此快照首次捕获于
- 2025/12/04 13:42 3 个月前
- 此快照最后确认于
- 2025/12/04 13:42 3 个月前
思路:
不难发现,如果把题目中要求的那些字符之间必须相等的关系抽象成图上的边,每个连通块内部都两两相等,就可以把这道题转化为一道基础图论题。注意到数据范围很小,所以我们可以把每个回文子串当中的每个下标枚举一遍,对应的字符看作给它们两个建了一条边,然后用并查集求解。不过答案可能很大,所以还要再加一个快速幂。
答案是什么呢?假设并查集求出来 个连通块,那么答案就是 。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k,mod=1e9+7,sum,fa[200005];
map<int,int>mp;
int find(int x){//并查集
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
int qpow(int a,int b){//快速幂
int ans=1,cnt=a;
while(b>0){
if(b&1==1)ans=ans*cnt%mod;
cnt=cnt*cnt%mod;
b>>=1;
}
return ans;
}
signed main () {
cin>>n>>m>>k;
if(k>n){//注意这个情况,容易漏掉
cout<<qpow(m,n)%mod;
return 0;
}
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n-k+1;i++){
for(int l=i,r=i+k-1;l<=r;l++,r--)fa[find(l)]=find(r);//建图
}
for(int i=1;i<=n;i++)mp[find(i)]=1;//求连通块个数
sum=qpow(m,mp.size());
cout<<sum%mod;
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...