CF 894 B/C 数学

Problem B
题意:n*m矩阵 每格填入1或者-1.问每行每列的乘积都为k的方案数 n,m<=1e18 k=1,-1.


前i-1行 前i-1列任填 则最后一行和最后一列填入的方案是固定的.

总乘积 k^n = k^m 若n,m奇偶性不同&&k==-1 则无解. 

否则最后一格(n,m)一定不会有冲突(为了满足最好一行填x ,为了满足最后一列填y 得到k^n ,k^m) 因为k^n=k^m 所以x=y 满足最后一行的同时也满足最后一列)


答案为2^(n-1)*(m-1) 快速幂算一下 (2^(n-1))^m-1即可.

#include 
using namespace std;
typedef long long ll;
const int N=2e5+5,mod=1e9+7;
ll n,m,k;
ll powmod(ll x,ll n)
{
	ll s=1;
	while(n)
	{
		if(n&1)
			s=(s*x)%mod;
		x=(x*x)%mod;
		n>>=1;
	}
	return s;
}
int main()
{
	cin>>n>>m>>k;
	if(k==-1&&(n%2)!=(m%2))
	{
		puts("0");
		return 0;
	}
	n--,m--;
	//n%=mod,m%=mod;
	ll ans=powmod(2ll,n);
	ans=powmod(ans,m);
	cout<




Problem C
题意:给出s:某个序列所有区间的gcd值. n<=1000,a[i]<=1e6  求出原序列.无解输出-1.

gcd(a,b)<=min(a,b) 原序列全部值的gcd肯定是s中的最小值s[1] 
所以原序列的数都为s[1]的倍数. -> 原序列任意区间的gcd也都为s[1]的倍数.

若存在s[i]不为s[1]的倍数 则无解

否则s[i],s[1]的放 显然满足条件. 

#include 
using namespace std;
typedef long long ll;
const int N=4e3+5,M=1e6+5;
int n,a[N],mk[M],vis[M];
vector b;
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]),vis[a[i]]=1;
	for(int i=1;i<=n;i++)
	{
		b.push_back(a[1]);
		b.push_back(a[i]);	
	}
	bool flag=true;
	for(int i=1;i<=n;i++)
		if(a[i]%a[1])
			flag=false;	 
	
	if(flag)
	{
		printf("%d\n",b.size());
		for(int i=0;i




你可能感兴趣的:(Codeforces,泛做,数学,------,基础)