zoukankan      html  css  js  c++  java
  • AGC023C Painting Machines

    题意

    有一排(n)个格子,(i)操作会使(i)(i+1)都变黑。
    一个操作序列的得分为染黑所有格子时所用的步数
    问所有排列的得分和。
    (nle 10^6)
    传送门

    思路

    有一个很直观的感觉:要枚举步数。然后问题就是如何在(O(1))时间内求出排列数。
    考虑(1)(n-1)是必须染的,剩下的操作只要相邻两个相差不超过(2)就好了。那么可以发现要么是一个挨着一个,要么是一个空一格,转化成求有多少种安排空格的方法。
    (k)个操作,取掉头尾(k-2)个,总共(k-1)个间隔,要放入((n-k)-1)个空格,所以可行的组合数使(C(k-1,n-k-1))然后再乘上(k!)以及剩下的((n-1-k)!),但发现有可能会有(k)步之前就完成的,只要减去(k-1)时的答案就好了

    #include <bits/stdc++.h>
    const int N=1000005,mu=1000000007;
    int inv[N],p[N],n,ans,last; 
    int ksm(int x,int y){
    	int ans=1;
    	for (;y;y>>=1,x=x*1ll*x%mu)
    		if (y&1) ans=1ll*ans*x%mu;
    	return ans;
    }
    int C(int x,int y){
    	return 1ll*p[x]*inv[y]%mu*inv[x-y]%mu;
    }
    int main(){
    	scanf("%d",&n);
    	p[0]=1;
    	for (int i=1;i<=n;i++) p[i]=1ll*i*p[i-1]%mu;
    	inv[n]=ksm(p[n],mu-2);
    	for (int i=n-1;i>=0;i--) inv[i]=inv[i+1]*1ll*(i+1)%mu;
    	for (int i=(n+1)/2;i<=n-1;i++){
    		int x=C(i-1,n-i-1)*1ll*p[i]%mu*p[n-i-1]%mu;
    		ans=(ans+i*1ll*(x-last+mu)%mu)%mu;
    		last=x;
    	}
    	printf("%d
    ",ans);
    }
    

    后记

    好神仙啊

  • 相关阅读:
    sh_09_字典的定义
    sh_08_格式化字符串
    sh_07_元组遍历
    sh_06_元组基本使用
    sh_05_列表遍历
    sh_04_列表排序
    sh_03_列表的数据统计
    图片懒加载
    UA池和ip代理池
    爬虫篇 --- 分布式爬虫
  • 原文地址:https://www.cnblogs.com/flyfeather6/p/11861022.html
Copyright © 2011-2022 走看看