zoukankan      html  css  js  c++  java
  • [CF1536F] Omkar and Akmar

    前言

    很不幸,我做过几乎一样的原题,而且不像木示木干OneInDark,我记得清清楚楚。

    幸运的是,当我读到这道题的时候,只剩3分钟了。而且利用仅有的3分钟,还把题读错了。

    题目

    CF

    洛谷

    题目大意:

    希拉斯·暗月正在有 (n) 个格子的轮盘上玩游戏。一个人玩没有意思,所以他叫上了二傻子,并且喊来了各方势力观战。为了表示对二傻子的尊敬,希拉斯·暗月让二傻子每局游戏都先手。

    这个游戏是这么玩的:两个人轮流往轮盘上放 (A,B) ,要求相邻两个格子的字母不能相同,我们假设每局游戏两个人都按最优策略行动。

    一旁的古神发现游戏过程数量竟然比自己的触手还多,于是打算问你究竟有多少种不同的游戏过程

    如果你不能在 (3s) 之内得出正确答案,就会被古神丢给一旁的食人魔。当然,安度因早就偷到了答案,古神也知道这一点,所以古神让安度因做评判。而安度因还忙着在酒馆偷牌,没有心思管你,所以他放了点水,要求你对 (10^9+7) 取模即可。

    (2le nle 10^6.)

    希望我没有误导你。

    讲解

    由于做过原题,我们可以得到一个结论:后手只要不自杀,就可以必胜。因为最终局面 (A)(B) 的数量一定相等,总数为偶数。

    所以我们很自然就想到枚举最终 (A)(B) 的数量,然后通过经典隔板法求解即可。

    注意要求的是不同的游戏过程,所以是有阶乘项的,最终答案为:

    [sum_{ile n,2|i}i! imes Bigg({n-k-1choose k-1}+ {n-kchoose k}Bigg) ]

    代码

    //12252024832524
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 1000005;
    const int MOD = 1e9 + 7;
    int n,ans;
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int fac[MAXN],ifac[MAXN];
    LL C(int x,int y)
    {
    	if(x < y || y < 0) return 0;
    	return 1ll * fac[x] * ifac[y] % MOD * ifac[x-y] % MOD;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read();
    	fac[0] = fac[1] = ifac[0] = ifac[1] = 1;
    	for(int i = 2;i <= n;++ i) ifac[i] = 1ll * (MOD - MOD/i) * ifac[MOD % i] % MOD;
    	for(int i = 2;i <= n;++ i) ifac[i] = 1ll * ifac[i-1] * ifac[i] % MOD,fac[i] = 1ll * fac[i-1] * i % MOD;
    	for(int i = 0;i <= n;i += 2)//枚举填位 
    	{
    		int k = n-i;
    		ans = (ans + C((n-1)-(k-1)-1,k-1) * fac[i]) % MOD;//1号位是空格 
    		ans = (ans + C(n-k,k) * fac[i]) % MOD;//1号位不是空格 
    	}
    	Put((ans << 1) % MOD);
    	return 0;
    }
    
  • 相关阅读:
    android 联系数据库
    shuffle一个简单的过程叙述性说明
    每天的学习经验:SharePoint 2013 定义自己添加的产品清单。Callout菜单项、文档关注、SharePoint服务机端对象模型查询
    函数调用
    InputMonitor注意事项
    处理FTP上传成功推理
    用Web技术开发客户端(一)
    简析Chrome和Webkit的渊源
    历史在重演:从KHTML到WebKit,再到Blink
    开发者应当了解的WebKit知识
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14878872.html
Copyright © 2011-2022 走看看