# [FR#12]被虐赛

A题题意：有一个序列a1...an,您需要回答m个询问,每个询问给一个b,使删除尽量少的数使得任意时刻前缀和都>=b(m<=10^4,n<=10^3)

设G(i)为i=gcd的a的贡献,G(i)=F(i)-G(2i)-G(3i)-...

AC Code:

B题：

#include<bits/stdc++.h>
#define maxn 10001000
using namespace std;
typedef long long ll;
int phi[maxn],m,n,p,phi2[maxn],pri[maxn],psz,vis[maxn];
int qpow(int a,int b,int p){
int ans=1,tmp=a;
for(;b;b>>=1,tmp=1ll*tmp*tmp%p)
if(b&1)ans=1ll*ans*tmp%p;
return ans;
}
int find(int k,int p){
//	printf("[%d,%d]\n",k,p);
if(k==0)return 1;
if(p==1)return 0;
return qpow(k,find(k,phi[p])+phi[p],p);
}
int main(){
scanf("%d%d%d",&m,&n,&p);
phi[1]=phi2[1]=1;
int lim=max(max(m,n),p);
for(int i=2;i<=lim;i++){
if(!vis[i]){pri[psz++]=i;phi[i]=i-1;phi2[i]=(m%i==0?i:i-1);}
for(int j=0;j<psz&&i*pri[j]<=lim;++j){
vis[i*pri[j]]=true;
if(i%pri[j]){
phi[i*pri[j]]=phi[i]*phi[pri[j]];
phi2[i*pri[j]]=phi2[i]*phi2[pri[j]];
} else {
phi[i*pri[j]]=phi[i]*pri[j];
phi2[i*pri[j]]=phi2[i]*pri[j];
}
}
}
ll k=0;
for(int i=1;i<=n;++i)k=(k+1ll*phi2[i]*phi[m])%1000000007;
//	printf("[%d]",k);
printf("%d",find(k,p));
}

C题：

#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
int f[1000100],F[1000100],G[1000100],a[50100],n,ans=1;
int qpow(int a,int b,int p){
int tmp=a,ans=1;
for(;b;b>>=1,tmp=1ll*tmp*tmp%p)
if(b&1)ans=1ll*ans*tmp%p;
return ans;
}
int main(){
f[0]=0,f[1]=1;
for(int i=2;i<=1000000;++i)f[i]=(f[i-1]+f[i-2])%mod;
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<=n;++i)
for(int j=1;j*j<=a[i];++j)if(a[i]%j==0){
F[j]++;if(j*j!=a[i])F[a[i]/j]++;
}
//	for(int i=1;i<=n;++i)ans=1ll*ans*f[a[i]]%mod;
//	printf("[%d]",ans);
for(int i=1000000;i>=1;--i){
G[i]=(F[i]!=0);
for(int j=2*i;j<=1000000;j+=i)
G[i]-=G[j];
//		if(G[i])printf("[%d:%d]",f[i],G[i]);
if(G[i]<0)ans=1ll*ans*qpow(f[i],mod-1+G[i],mod)%mod;
else if(G[i])ans=1ll*ans*qpow(f[i],G[i],mod)%mod;
}
printf("%d",ans);
}