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;
    }
    
  • 相关阅读:
    返回表对象的方法之一--bulk collect into
    coolite 获取新的页面链接到当前页面指定位置Panel的运用
    oracle 当前年到指定年的年度范围求取
    JAVA WEB 过滤器
    Java复习笔记(二):数据类型以及逻辑结构
    Java复习笔记(一):概念解释和运行步骤
    装饰器理解
    Flask大型项目框架结构理解
    JSP内置对象(一)
    Java Web第一个应用搭建
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14764499.html
Copyright © 2011-2022 走看看