列表

详情


NC20597. [TJOI2017]龙舟

描述

加里敦大学有一个龙舟队,龙舟队有n支队伍,每只队伍有m个划手,龙舟比赛是一个集体项目,和每个人的能力息息相关,但由于龙舟讲究配合,所以评价队伍的能力的是一个值c = (b1*b2...*bm)/(a1*a2...*am),其中bi表示第i个位置标准能力值,ai表示在队伍中第i个位置的划手的能力值。
最后通过约分,我们会得到c= B/A,其中gcd(B,A)=1,即A, B是互质的,但是由于比赛现场的情况不一样,我们认为在现场压力为M的情况下,队伍最后的表现情况认为是C=1(mod M)我们规定在模M的条件下1/x = y,其中y满足xy=1(mod M)并且y是大于等于0,并且小于M的值,如果不存在这 样的y我们就认为在M的条件下这支队伍会发挥失常(即y是x在模M意义下的逆元,如果不存在逆元我们认为队伍发挥失常)。
现在是这个赛季的比赛安排情况,现在教练组想知道各队的在比赛中表现情况。

输入描述

第一行输入三个个整数n, m,k,表示有n支队伍,每支队伍有m个人组成,有k场比赛
第二行输入m个整数,第i个表示表征第i个位置的标准能力值为bi
第3行到第n +2行,共n行,每行有m个数,第2+i行第j个数表示第i支队伍的第j个位置的划手的能力值
第n + 3行到第n + k + 2行,共n行,每行有两个数x,M,分别表示第x支队伍会在压力为M的比赛中出战

输出描述

共k行,第i行表示在第i个参赛安排种队伍的现场表现情况C,如果出现队伍发挥失常,输出“-1”

示例1

输入:

2 3 3
5 2 3
3 2 3
2 3 2
1 4
2 4
1 7

输出:

3
-1
4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 494ms, 内存消耗: 5980K, 提交时间: 2020-09-25 17:04:34

#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
const int N = 1e4 + 2;
ll p[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
ll A[21][N], B[N], aa[N], bb[N], fac[N], prifac[N];
ll qp(ll a,ll x,ll mod){
	ll i = 1;
	for(;x; x >>= 1, a = (__int128)a * a % mod)if(x & 1)i = (__int128)i * a % mod;
	return i;
}
ll gcd(ll a,ll b){
	ll r;
	while(b)r = a % b, a = b, b = r;
	return a;
}
bool isPrime(ll n){
	ll i, x = n - 1, a, y, j, z;
	if(n == 2)return 1;
	if(n <= 1 || (n & 1 ^ 1))return 0;
	for(a = 0;x & 1 ^ 1;a++, x >>= 1);
	for(i = 0;i < 10 && p[i] < n;i++){
		y = qp(p[i], x, n);
		for(j = 0;j < a;j++, y = z){
			z = (__int128)y * y % n;
			if(z == 1 && y != 1 && y != n - 1)return 0;
		}if(y != 1)return 0;
	}
	return 1;
}
ll getfac(ll n, ll c){
	ll d, x = 1ll * rand() * rand() % (n - 1) + 1, y = x, k = 1, i, s = 1;
	for(i = d = 1; d == 1;i++){
		x = ((__int128)x * x % n + c) % n;
		s = (__int128)s * abs(x - y) % n;
		if(x == y || !s)return n;
		d = gcd(s, n);
		if(i == k){
			d = gcd(s, n);
			y = x;k <<= 1;
		}
	}return d;
}
void rho(ll n){
	if(n <= 1)return;
	if(isPrime(n)){
		prifac[++prifac[0]] = n;
		return;
	}ll t = n;
	while(t == n)t = getfac(n, 1ll * rand() * rand() % n + 1);
	while(!(n % t))n /= t;
	rho(t);rho(n);
}
int main(){
	ll n, m, T, i, j, mod, k, phi;
	scanf("%lld%lld%lld", &n, &m, &T);
	for(i = 1;i <= m;i++)scanf("%lld", &B[i]);
	for(i = 1;i <= n;i++)for(j = 1;j <= m;j++)scanf("%lld", &A[i][j]);
	while(T--){
		scanf("%lld%lld", &n, &mod);
		prifac[0] = 0;rho(mod);
		sort(prifac + 1, prifac + prifac[0] + 1);
		prifac[0] = unique(prifac + 1, prifac + prifac[0] + 1) - prifac - 1;
		for(i = 1;i <= prifac[0];i++)fac[i] = 0;
		for(i = 1;i <= m;i++)aa[i] = A[n][i], bb[i] = B[i];
		for(k = 1, phi = mod;k <= prifac[0];phi -= phi / prifac[k++])
			for(i = 1;i <= m;i++){
				for(;!(bb[i] % prifac[k]);bb[i] /= prifac[k], fac[k]++);
				for(;!(aa[i] % prifac[k]);aa[i] /= prifac[k], fac[k]--);
			}
		for(k = j = 1;k <= prifac[0] && fac[k] >= 0;k++)j = (__int128)j * qp(prifac[k], fac[k], mod) % mod;
		if(k > prifac[0]){
			for(i = k = 1;i <= m;i++){
				j = (__int128)j * bb[i] % mod;
				k = (__int128)k * aa[i] % mod;
			}j = (__int128)j * qp(k, phi - 1, mod) % mod;
		}else j = -1;
		printf("%lld\n", j);
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 510ms, 内存消耗: 2040K, 提交时间: 2020-08-10 11:54:56

#include <bits/stdc++.h>
using namespace std;
#define ll long long
inline ll read()
{
	ll x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
ll Multi(ll x,ll y,ll MOD){ll s=x*y-(ll)((long double)x/MOD*y+0.5)*MOD;return s<0?s+MOD:s;}
ll fpow(ll a,ll b,ll MOD){ll s=1;while(b){if(b&1)s=Multi(s,a,MOD);a=Multi(a,a,MOD);b>>=1;}return s;}
bool Miller_Rabin(ll n)
{
	if(n==2)return true;
	for(int tim=10;tim;--tim)
	{
		ll a=rand()%(n-2)+2,p=n-1;
		if(fpow(a,n-1,n)!=1)return false;
		while(!(p&1))
		{
			p>>=1;ll nw=fpow(a,p,n);
			if(Multi(nw,nw,n)==1&&nw!=1&&nw!=n-1)return false;
		}
	}
	return true;
}
ll Pollard_Rho(ll n,int c)
{
	ll i=0,k=2,x=rand()%(n-1)+1,y=x;
	while(233)
	{
		++i;x=(Multi(x,x,n)+c)%n;
		ll d=__gcd((y-x+n)%n,n);
		if(d!=1&&d!=n)return d;
		if(x==y)return n;
		if(i==k)k<<=1,y=x;
	}
}
void Fact(ll n,int c,vector<ll> &fac)
{
	if(n==1)return;
	if(Miller_Rabin(n)){fac.push_back(n);return;}
	ll p=n;while(p>=n)p=Pollard_Rho(n,c--);
	Fact(p,c,fac);Fact(n/p,c,fac);
}
int n,m,Q;ll a[25][10100];
int pri[100];
int main()
{
	n=read();m=read();Q=read();
	for(int i=0;i<=n;++i)
		for(int j=1;j<=m;++j)a[i][j]=read();
	while(Q--)
	{
		int x=read();ll MOD=read(),phi=MOD;int tot;
		vector<ll> fac;Fact(MOD,233,fac);
		sort(fac.begin(),fac.end());fac.resize(tot=unique(fac.begin(),fac.end())-fac.begin());
		for(int i=0;i<tot;++i)phi=phi-phi/fac[i];
		ll inv=1,ans=1;
		for(int i=1;i<=m;++i)
		{
			ll p=a[0][i];
			for(int j=0;j<tot;++j)
				while(p%fac[j]==0)p/=fac[j],++pri[j];
			ans=Multi(ans,p,MOD);
		}
		for(int i=1;i<=m;++i)
		{
			ll p=a[x][i];
			for(int j=0;j<tot;++j)
				while(p%fac[j]==0)p/=fac[j],--pri[j];
			inv=Multi(inv,p,MOD);
		}
		bool fl=true;
		for(int i=0;i<tot;++i)if(pri[i]<0){fl=false;break;}
		if(fl)
		{
			for(int i=0;i<tot;++i)if(pri[i])ans=Multi(ans,fpow(fac[i],pri[i],MOD),MOD);
			ans=Multi(ans,fpow(inv,phi-1,MOD),MOD);printf("%lld\n",ans);
		}
		else puts("-1");
		for(int i=0;i<tot;++i)pri[i]=0;
	}
	return 0;
}

上一题