QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#134480 | #6399. Classic: Classical Problem | stefanbalaz2 | TL | 13ms | 14352kb | C++14 | 5.6kb | 2023-08-03 20:49:47 | 2023-08-03 20:49:50 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define pb push_back
#define ll long long
typedef pair<int,int> pii;
int mod=998244353;
const double dmod=(double)1/mod;
inline int add(int x,int y){int ret=x+y;if(ret>=mod)ret-=mod;return ret;}
inline int sub(int x,int y){int ret=x-y;if(ret<0)ret+=mod;return ret;}
inline int mul(int x,int y){
ll ret=(ll)x*y;
ret=ret-((ll)(dmod*ret))*mod;
if(ret<0)ret+=mod;
if(ret>=mod)ret-=mod;
return ret;
return ((ll)x*y)%mod;
}
inline int step(int base,int pw){int ret=1;while(pw){if(pw&1)ret=mul(ret,base);base=mul(base,base);pw>>=1;}return ret;}
inline int invv(int x){return step(x,mod-2);}
const int maxn=(1<<20);
int proot=step(3,7*17*8);
int prekw[maxn];
int g,a[maxn],n,mp[maxn],b[maxn],c[maxn];
void prek(){
for(int i=2;i<maxn;i++){
if(mp[i])continue;
for(int j=i;j<maxn;j+=i){
if(!mp[j])mp[j]=i;
}
}
prekw[0]=1;
for(int i=1;i<maxn;i++)
prekw[i]=mul(prekw[i-1],proot);
}
vector<int> factorise(int n){
vector<int>ret;
while(n>1){
if(ret.size()==0)ret.pb(mp[n]);
else if(ret.back()!=mp[n])ret.pb(mp[n]);
n/=mp[n];
}
return ret;
}
int get_gen(int p){
if(p==2)return 1;
p--;
vector<int>fact=factorise(p);
for(int i=1;i<=p;i++){
int e=1;
for(int j=0;j<fact.size();j++){
if(step(i,p/fact[j])==1){
e=0;break;
}
}
if(e)return i;
}
return -1;
}
vector<int>resetfb;
int resetb=0;
void fft(vector<int>&a,bool invert){
int n=a.size();
int j=0;
for(int i=1;i<n;i++){
int bit=n>>1;
for(;bit&j;bit>>=1)j^=bit;
j^=bit;
if(i<j)swap(a[i],a[j]);
}
for(int len=2;len<=n;len<<=1){
for(int i=0;i<n;i+=len){
int cw=maxn/len;
if(invert)cw=maxn-cw;
int curr=0;
for(int j=0;j<len/2;j++){
int pom1=a[i+j];
int pom2=mul(a[i+j+len/2],prekw[curr]);
a[i+j]=add(pom1,pom2);
a[i+j+len/2]=sub(pom1,pom2);
curr+=cw;
if(curr>=maxn)curr-=maxn;
}
}
}
if(invert){
int invn=invv(n);
for(int i=0;i<n;i++)
a[i]=mul(a[i],invn);
}
}
int brute_par=500;
vector<int>pol_mul_brute(vector<int>a,vector<int>b){
vector<int>ret(a.size()-1+b.size()-1+1);
for(int i=0;i<a.size();i++)
for(int j=0;j<b.size();j++){
ret[i+j]=add(ret[i+j], mul(a[i],b[j]) );
}
return ret;
}
vector<int> pol_mul(vector<int>a,vector<int>b){
while(a.size() && a.back()==0)a.pop_back();
while(b.size() && b.back()==0)b.pop_back();
/*if(a.size()*b.size()<brute_par){
return pol_mul_brute(a,b);
}*/
int n=2;
while(n<a.size()-1+b.size()-1+1)n<<=1;
a.resize(n);
b.resize(n);
int ppp=mod;
mod=998244353;
fft(a,0);
if(resetb){
fft(b,0);
resetfb=b;
resetb=0;
}
else b=resetfb;
for(int i=0;i<n;i++)
a[i]=mul(a[i],b[i]);
fft(a,1);
mod=ppp;
return a;
}
void ispis(vector<int>a){
for(int i=0;i<a.size();i++)printf("%d ",a[i]);
printf(" ISPIS \n");
}
vector<int> va,vb;
vector<int> check(int x){
va.clear();
va.resize(2*mod-2);
int cn=mod-1;
for(int i=0;i<va.size();i++){
if( b[i%cn]<=x )va[i]=1;
else va[i]=0;
}
// printf("%d XXX\n",x);
// ispis(va);
vector<int>ret=pol_mul(va,vb);
//vector<int>bla=burt(va,vb);
// ispis(ret);
//ispis(bla);
vector<int>rr;
for(int i=0;i<cn;i++){
///printf()
if(ret[i+cn-1]==x)rr.pb(b[i]);
}
return rr;
}
int main() {
prek();
/*vector<int>bb,aa;
aa.pb(1);
aa.pb(1);
bb.pb(2);
bb.pb(3);
aa=pol_mul(aa,bb);
ispis(aa);*/
///freopen("test.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&mod);
resetb=1;
int e=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==0){
e=1;
n--;
i--;
}
}
if(!e){
printf("%d %d\n0\n",1,1);
continue;
}
g=get_gen(mod);
/// ako je mex==0 onda dodaj i 0 u rez
//printf("%d GEN\n",g);
int curr=1;
for(int i=0;i<mod-1;i++){
b[i]=curr;
c[curr]=i;
//printf("%d %d BC\n",i,curr);
curr=mul(curr,g);
}
vb.clear();
vb.resize(mod-1);
for(int i=1;i<=n;i++){
vb[c[a[i]]]=1;
}
//ispis(vb);
reverse(vb.begin(),vb.end());
int l=0;
int r=mod-1;
int sr,ret=-1;
while(l<=r){
sr=(l+r)/2;
vector<int>pom=check(sr);
if(pom.size()==0){
r=sr-1;
}
else{
l=sr+1;
ret=sr;
}
}
vector<int>rr=check(ret);
ret++;
if(ret==1)rr.pb(0);
printf("%d %d\n",rr.size(),ret);
sort(rr.begin(),rr.end());
for(int i=0;i<rr.size();i++)printf("%d ",rr[i]);
printf("\n");
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 13ms
memory: 14352kb
input:
3 2 3 0 2 3 5 2 3 4 3 5 0 2 3
output:
1 2 2 1 1 0 2 2 2 3
result:
ok 6 lines
Test #2:
score: -100
Time Limit Exceeded
input:
3 1 2 0 1 2 1 2 2 1 0