zoukankan      html  css  js  c++  java
  • [ABC200F] Minflip Summation

    前言

    太妙啦!

    本文只讲做法,不讲如何想到这个做法,没见过这个套路真的很难想啊。

    题目

    AtCoder

    讲解

    part1 01

    我们先考虑没有问号的情况。

    我们将所有数变为与第一个数相同的方法一定不劣。那么我们可以想到这样一个统计答案的方法,如果相邻两个数(按环考虑)不同,那么对答案的贡献为 (frac{1}{2})。用 (C++) 表示即:

    [frac{overset{|S|}{underset{i=1}{sum}}S_i==S_{i\%|S|+1} ? 0 : 1}{2} ]

    反复 (K) 次只需要将答案乘 (K) 即可。

    part2 ?

    考虑扩展版本。

    我们发现每个 (?) 成为 (0)(1) 的概率相同,而且彼此独立,所以我们可以求出期望再求出答案。

    此时的答案为:

    [Kcdot frac{overset{|S|}{underset{i=1}{sum}}f(i,i\%|S|+1)}{2}cdot 2^{cnt_?K} ]

    其中的函数 (f(x,y)) 表示 (S_x,S_y) 对答案产生的贡献。

    • (S_x)(S_y) 其中一个是问号,那么显然对答案的贡献为 (frac{1}{2})
    • 否则相同贡献 (0),不同贡献 (1)

    代码

    int qpow(int x,int y)
    {
    	int ret = 1;
    	while(y){if(y & 1) ret = 1ll * ret * x % MOD;x = 1ll * x * x % MOD;y >>= 1;}
    	return ret;
    }
    int Add(int x,int y)
    {
    	x += y; if(x >= MOD) x -= MOD;
    	return x;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	scanf("%s",a+1);
    	n = strlen(a+1); k = Read();
    	for(int i = 1;i <= n;++ i)
    	{
    		int j = i+1 > n ? 1 : i+1; 
    		if(a[i] == '?')	
    		{
    			cnt++;
    			ans = Add(ans,inv2);
    		}
    		else if(a[j] == '?') ans = Add(ans,inv2);
    		else if(a[i] != a[j]) ans = Add(ans,1);
    	}
    	ans = 1ll * ans * k % MOD * inv2 % MOD * qpow(2,1ll * cnt * k % (MOD-1)) % MOD;
    	Put(ans);
    	return 0;
    }
    
  • 相关阅读:
    说一说Java的Unsafe类
    阿里云CentOS下安装jdk
    LeetCode 5
    五种方法实现Java的Singleton单例模式
    聊聊Java的final关键字
    LeetCode 4
    Java9都快发布了,Java8的十大新特性你了解多少呢?
    【Spring】mvc:annotation-driven 使用
    【gradle】【maven】gradle 转 maven pom.xml
    [GIT]比较不同分支的差异
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14764499.html
Copyright © 2011-2022 走看看