結果
| 問題 |
No.1956 猫の額
|
| ユーザー |
👑 testestest
|
| 提出日時 | 2022-04-10 05:21:29 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,209 bytes |
| コンパイル時間 | 1,951 ms |
| コンパイル使用メモリ | 34,432 KB |
| 実行使用メモリ | 12,452 KB |
| 最終ジャッジ日時 | 2024-09-20 13:36:43 |
| 合計ジャッジ時間 | 37,869 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 4 TLE * 1 -- * 16 |
ソースコード
#include<stdio.h>
#include<stdlib.h>
#define ll long long
ll inv(ll x, int mod){
if(x==1)return 1;
return (1-inv(mod%x,x)*mod)/x+mod;
}
ll modpow(ll x,ll n,ll m){
if(n==0)return 1;
ll ret=modpow(x,n/2,m);
ret=ret*ret%m;
if(n%2)return ret*x%m;
return ret;
}
ll witness[]={2,7,61};
int isprime(int n){
if(n==2)return 1;
if(n<2||n%2==0)return 0;
ll d=(n-1)/(n-1&1-n);
for(int i=0;i<3;i++){
if(witness[i]>=n)return 1;
ll t=d;
ll a=modpow(witness[i],t,n);
if(a==1||a==n-1)continue;
while(a!=n-1){
t*=2;
a=a*a%n;
if(t==n-1)return 0;
if(a==1)return 0;
}
}
return 1;
}
ll calc_primitiveroot(int P){
int remainder[32]={};
int cnt=0;
int ord=P-1;
for(ll i=2;i*i<=ord;i++)if(ord%i==0){
while(ord%i==0)ord/=i;
remainder[cnt++]=P/i;
}
if(ord!=1)remainder[cnt++]=P/ord;
for(ll g=2;;g++){
int flag=1;
for(int i=0;i<cnt;i++)if(modpow(g,remainder[i],P)==1)flag=0;
if(flag)return g;
}
}
int garner(ll*r,ll*m,int M){
int n=4;
ll k[4];
for(int i=0;i<n;i++){
ll a=0,b=1;
for(int j=0;j<i;j++){
a=(a+b*k[j])%m[i];
b=(b*m[j])%m[i];
}
k[i]=(r[i]-a+m[i])*inv(b,m[i])%m[i];
}
ll a=0,b=1;
for(int i=0;i<n;i++){
a=(a+b*k[i])%M;
b=(b*m[i])%M;
}
return (a+M)%M;
}
/////////////////////////
int N,S;
int A[100];
ll temp[100010];
void solve(int P,int c,ll*dp){
ll g=calc_primitiveroot(P);
ll z=modpow(g,P/c,P);
ll zeta=1;
for(int zeta_i=0;zeta_i<c;zeta_i++,zeta=zeta*z%P){
for(int i=0;i<=S;i++)temp[i]=0;
temp[0]=1;
int sum=0;
for(int i=0;i<N;i++){
for(int j=sum;j>=0;j--)temp[j+A[i]]=(temp[j+A[i]]+temp[j]*zeta)%P;
sum+=A[i];
}
for(int i=0;i<=S;i++)dp[i]+=temp[i];
}
int invc=inv(c,P);
for(int i=0;i<=S;i++)dp[i]=dp[i]%P*invc%P;
dp[0]=0;
}
ll ans[4][100010];
int main(){
int mod,C;
scanf("%d%d%d",&N,&mod,&C);
for(int i=0;i<N;i++)scanf("%d",&A[i]);
for(int i=0;i<N;i++)S+=A[i];
int CC=2*C>=N?C:N-C;
int P=1000000000/CC*CC+1;
ll Ps[4];
for(int i=0;i<4;i++,P+=CC){
while(!isprime(P))P+=CC;
solve(P,CC,ans[i]);
Ps[i]=P;
}
ll r[4];
for(int i=1;i<=S;i++){
for(int j=0;j<4;j++)r[j]=ans[j][2*C>=N?i:S-i];
int ret=garner(r,Ps,mod);
if(i==S&&2*C==N)ret=(ret-1+mod)%mod;
printf("%d%c",ret,i==S?10:32);
}
}
testestest