zoukankan      html  css  js  c++  java
  • GCD of Sequence

    题目大意:
    给定一个长度为n的序列a以及值域[1,m],要求构造b满足(b_i)属于[1,m]且(b_i!=a_i)的关系恰有k对
    没用莫反做
    一开始想的很复杂,后来发现求i的答案不好求,改成求i的倍数的
    也就是单独求gcd=i的很难,但如果改为i的倍数,就可以只考虑所选数是不是i的倍数。
    有k次机会来改变a序列,如果某个数不是i的倍数,就必须给他一个机会,不然的话就可改可不改。
    然后柿子就显然了。

    	#include<cstdio>
    #include<iostream>
    using namespace std;
    const int N=3e5+7,maxn=3e5,mod=1e9+7;
    inline int read() {
    	int x=0;char c=getchar();
    	for(;c<'0'||c>'9';c=getchar());
    	for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-48;
    	return x;
    }
    int js[N],inv[N],c[N],f[N],g[N];
    inline int C(int n,int m) {
    	if(m<0||m>n) return 0;
    	return 1ll*js[n]*inv[m]%mod*inv[n-m]%mod;
    }
    inline int qpow(int a,int b,int c=1) {
    	for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) c=1ll*c*a%mod;
    	return c;
    }
    inline void moded(int &x) {
    	if(x>=mod) x-=mod;if(x<0) x+=mod;
    }
    signed main() {
    	js[0]=inv[0]=1;
    	for(int i=1;i<=maxn;++i) js[i]=1ll*js[i-1]*i%mod;
    	inv[maxn]=qpow(js[maxn],mod-2);
    	for(int i=maxn-1;i;--i) inv[i]=1ll*inv[i+1]*(i+1)%mod;
    	int n,m,k;
    	while(scanf("%d%d%d",&n,&m,&k)!=EOF) {
    		for(int i=1;i<=m;++i) c[i]=0;
    		for(int i=1;i<=n;++i) c[read()]++;
    		for(int i=m;i;--i) {
    			int tt=0;
    			for(int j=1;i*j<=m;++j) tt+=c[i*j];f[i]=0;
    			if(n-tt>k) continue;
    			f[i]=1ll*C(tt,k-(n-tt))*qpow(m/i-1,k-(n-tt))%mod*qpow(m/i,n-tt)%mod;
    		}
    		for(int i=m;i;--i) for(int j=2;j*i<=m;++j) moded(f[i]=f[i]-f[i*j]);
    		for(int i=1;i<=m;++i) printf("%d ",f[i]);
    		puts("");
    	}
    	return 0;
    }
  • 相关阅读:
    POJ 3977 折半枚举
    [CQOI2007]余数求和 (分块+数学
    NOI P1896 互不侵犯 状压DP
    HDU 5446 Unknown Treasure (卢卡斯+CRT
    宁夏邀请赛F FLOYD
    P1414 又是毕业季II (数学?
    P2051 [AHOI2009]中国象棋 DP
    POJ 2449:Remmarguts' Date(A* + SPFA)
    HDU 6215:Brute Force Sorting(链表+队列)
    HDU 6207:Apple(Java高精度)
  • 原文地址:https://www.cnblogs.com/hzoi-kx/p/12120942.html
Copyright © 2011-2022 走看看