HDU - 3461 Code Lock (并茶几,区间合并)

🔊 🔊 🔊

题读了半天
题意:有一个长为n的字符串,同时该字符串上有m 个可以一起翻转的区间,如果两种字符串可以通过翻转相同,则视为一种字符串,问你长为n 的这个字符串有几种情况。
比如长为1的时候,如果没有可翻转的字符串,那就有26种情况,如果1这个位置可以翻转,那么a=b=c=d=…一共就是一种字符串。
(1)容易发现如果没有可翻转的字符串,答案即为26^n
(2)每加入一个区间,方案数就减去一个幂次,例如下图中的1234这四个位置,本来我们可改变的是这四个位置,但是该区间可以一起翻转之后,我们可以改变的就只有他们互相之间的差值(即圈出的地方)
(3)考虑区间(1,3)(4,5)(1,5),我们发现(1,5)是不起作用的,也就是说有的区间对答案没有贡献
(4)考虑(1,3)(3,4),这两个区间有交集3,(3,4)对大难依然有贡献
(5)综合后发现L,R+1在同一并茶几的区间无贡献
在这里插入图片描述//暴力

const int mod = 1e9+7;
ll qpow(int a,int b)//a^b//快速幂
{
    if(b==0) return 1;
    a%=mod;
    ll ans=1,temp=a;
	while(b)
	{
		if(b&1)	 ans=(ans*temp)%mod;
		temp=(temp*temp)%mod;
		b>>=1;
	}
	return ans%mod;
}
int n,m,f[MAXN];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
bool mix(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx==fy) return 0;
    f[fx]=fy;
    return 1;
}
signed main()
{
    while(~scanf("%d %d",&n,&m))
    {
        int ans=0;
        rep(i,0,1e7+1) f[i]=i;
        rep(i,1,m)
        {
            int l,r;rd(l),rd(r);
            if(mix(l,r+1)) ++ans;
        }
        cout<<qpow(26,n-ans)<<endl;
    }
 //   stop;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值