zoukankan      html  css  js  c++  java
  • 【纪中集训2019.3.25】礼物

    题目

    描述

    ​ 一个(n)个珠子的手环,你可以选择其中(m)个将其染成金色;

    ​ 但是连续的金色段的长度不能超过一个阈(yu,四声)值;

    ​ 求:在旋转置换下的本质不同的方案数;

    ​ 答案对(998244353)取模;

    范围

    ​ $1 le T le 5 , 1 le n le 10^6 , 0 le k le m le n $ ;

    题解

    • 和这个题类型差不多:
      https://www.cnblogs.com/Paul-Guderian/p/10590523.html

    • 同样有两种推法:

    • (f(n,m))为不计旋转置换下的方案;

    • 首先套用(polya)

    • [egin{align} ans &= frac{1}{n}sum_{d=1}^{n} f(gcd(d,n),frac{m}{frac{n}{gcd(d,n)}})[frac{n}{gcd(d,n)}|m]\ &= frac{1}{n}sum_{d|(n,m)}f(frac{n}{d},frac{m}{d})phi(d) end{align} ]

    • 给出两种推(f(n,m))的方法;

      [考虑在先搞好剩下的n-m个无色珠子,然后将m个金珠子插进去,注意分两边和中间插\ 容易得到答案对m的生成函数:F(x) = (sum_{i=0}^{k}x^i)^{n-m-1}(sum_{i=0}^{k}(i+1)x^i)\ 令G(x)=sum_{i=0}^{k}(i+1)x^i\ xG(x) = sum_{i=1}^{k+1}ix^i = G(x) - sum_{i=0}^{k}x^i + x^{k+1}(k+1) \ G(x) = frac{1-x^{k+1}(k+1)+x^{k+2}(k+1)}{(1-x)^2}\ 那么:\ F(x) = frac{(1-x^{k+1})^{n-m-1}}{(1-x)^{n-m+1}}[1-x^{k+1}(k+2)+x^{k+2}(k-1)]\ 用二项式定理和广义二项式定理(或者直接说泰勒展开)展开左边;\ 直接求的复杂度是frac{sigma(m)}{k+1}的\sigma(m)接近n loglog n ;\ 所以复杂度接近线性; ]

    • 另外一种是直接从组合的意义去计算(f(n,m))

      [直接考虑去染金m个连续不超过k的珠子比较麻烦;\ 考虑成将n-m个珠子染黑,然后相邻两个珠子之间的距离不超过k\ 下文的m均指原定义中的n-m\ 考虑限定第一个珠子是黑色的,最后的放案需要乘以frac{n}{m}\ 相当于选取m个整数变量,满足:\ 1. 0 le a_0,a_1,...a_{m-1}le k\ 2. a_0+a_1+cdots+a_{m-1} = n-m\ 容斥1,插隔板统计2,可得最后的答案\ frac{n}{m}sum_{i=1}^{k}(-1)^i(^m_i)(^{n-1-(k+1)i}_{m-1});\ 类似复杂度分析\ ]

      #include<bits/stdc++.h>
      #define ll long long 
      #define mod 998244353
      using namespace std;
      const int N=1000010;
      int n,m,k,iv[N],fac[N],inv[N],vis[N],pr[N],phi[N],pt;
      int pw(int x,int y){
      	int re=1;
      	while(y){
      		if(y&1)re=(ll)re*x%mod;
      		y>>=1;x=(ll)x*x%mod;
      	}
      	return re;
      }
      void pre(){
      	iv[1]=1;for(int i=2;i<=1000000;++i)iv[i]=(ll)(mod-mod/i)*iv[mod%i]%mod;
      	for(int i=fac[0]=inv[0]=1;i<=1000000;++i){
      		fac[i]=(ll)fac[i-1]*i%mod;
      		inv[i]=(ll)inv[i-1]*iv[i]%mod;
      	}
      	phi[1]=1;
      	for(int i=2;i<=1000000;++i){
      		if(!vis[i])phi[pr[++pt]=i]=i-1;
      		for(int j=1,t;j<=pt&&i*pr[j]<=1000000;++j){
      			vis[t=i*pr[j]]=1;
      			if(i%pr[j]==0){phi[t]=phi[i]*pr[j];break;}
      			else phi[t]=phi[i]*(pr[j]-1);
      		}
      	}
      }
      int C(int x,int y){return x<y?0:(ll)fac[x]*inv[y]%mod*inv[x-y]%mod;}
      int cal(int n,int m){
      	if(n<=m)return 0;
      	m=n-m;
      	int re=0;
      	for(int i=0;i<=m&&i*k<n;++i){
      		int now=(ll)C(m,i)*C(n-1-i*k,m-1)%mod;
      		if(i&1)re=(re-now+mod)%mod;
      		else re=(re+now)%mod;
      	}
      	return (ll)re*n%mod*iv[m]%mod;
      }
      int main(){
      	freopen("gift.in","r",stdin);
      	freopen("gift.out","w",stdout);
      	pre();
      	int T;scanf("%d",&T);
      	while(T--){
      		scanf("%d%d%d",&n,&m,&k);k++;
      		if(!m){puts("1");continue;}
      		int ans=0;
      		for(int i=1;i<=n&&i<=m;++i)if(n%i==0&&m%i==0){
      			ans=(ans+(ll)cal(n/i,m/i)*phi[i]%mod)%mod;
      		}
      		ans=(ll)iv[n]*ans%mod;
      		cout<<ans<<endl;
      	}
      	return 0;
      }
      
      
  • 相关阅读:
    2021杭电多校4 1003/HDU 6987 Cycle Binary
    2021牛客多校5 G/nowcoder 11256 G Greater Integer, Better LCM
    2021牛客多校4 G/nowcoder 11255 G Product
    2021牛客多校4 H/nowcoder 11255 H Convolution
    FFT/NTT字符串模糊匹配
    Codeforces Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 + Div. 2)
    2021杭电多校2 1006/HDU 6966 I love sequences
    2021牛客多校3 E/nowcoder 11254 E Math
    2021杭电多校1 1011/HDU 6960 Necklace of Beads
    linux操作系统使用小技巧,把程序和数据彻底分开
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10640299.html
Copyright © 2011-2022 走看看