QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#104423#6399. Classic: Classical ProblemchangtuWA 2ms5708kbC++235.7kb2023-05-10 17:42:322023-05-10 17:42:35

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-10 17:42:35]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:5708kb
  • [2023-05-10 17:42:32]
  • 提交

answer

#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
// #define debug(x) cout<<"[debug]"#x<<"="<<x<<endl
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const ld eps=1e-8;
const int INF=0x3f3f3f3f;

#define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
#define debug(...)
#include<debug>
#else
#define debug(...)
#endif

namespace NTT
{
    typedef vector<ll> Poly;
    const int mod=998244353,G=3,Gi=332748118;
    const int M=6e5;//TODO
    int bit,tot;
    int rev[M];
    ll qmi(ll a,ll b,ll p)
    {
        ll res=1;
        while(b)
        {
            if(b&1)
            res=res*a%p;

            a=a*a%p;
            b>>=1;
        }
        return res;
    }
    void NTT(Poly &a,int inv)
    {
        for(int i=0;i<tot;i++)
            if(i<rev[i]) swap(a[i],a[rev[i]]);
    
        for(int mid=1;mid<tot;mid*=2)
        {
            ll w1=qmi(inv==1?G:Gi,(mod-1)/(2*mid),mod);
            for(int i=0;i<tot;i+=mid*2)
            {
                ll wk=1;
                for(int j=0;j<mid;j++,wk=wk*w1%mod)
                {
                    ll x=a[i+j];
                    ll y=wk*a[i+j+mid]%mod;
                    a[i+j]=(x+y)%mod;
                    a[i+j+mid]=(x-y+mod)%mod;
                }
            }
        }
    
        if(inv==-1)//就不用后面除了
        {
            ll intot=qmi(tot,mod-2,mod);
            for(int i=0;i<tot;i++)
            {
                a[i]=a[i]*intot%mod;
            }
        }
    }
    Poly mul(Poly a,Poly b)//deg是系数的数量,所以有0~deg-1次项
    {
        int deg=(int)a.size()+b.size()-1;
        bit=0;
        while((1<<bit)<deg) bit++;//至少要系数的数量
        tot=1<<bit; //系数项为0~tot-1
        for(int i=0;i<tot;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));

        Poly c(tot);
        a.resize(tot),b.resize(tot);
        NTT(a,1),NTT(b,1);
        for(int i=0;i<tot;i++) c[i]=a[i]*b[i]%mod;
        NTT(c,-1);
        c.resize(deg);
        return c;
    }
    Poly operator *(const Poly &a,const Poly &b)
    {
        return mul(a,b);
    }
    Poly operator *(const Poly &a,const int &t)
    {
        Poly res;
        for(int i=0;i<a.size();i++) res.push_back(1ll*a[i]*t%mod);
        return res;
    }
    Poly operator *(const Poly &a,const ll &t)
    {
        Poly res;
        for(int i=0;i<a.size();i++) res.push_back(a[i]*t%mod);
        return res;
    }
    Poly operator +(const Poly &a,const Poly &b)
    {
        Poly res(a);
        res.resize(max(a.size(),b.size()));
        for(int i=0;i<b.size();i++) res[i]=(res[i]+b[i])%mod;
        return res;
    }
    Poly operator -(const Poly &a,const Poly &b)
    {
        Poly res(a);
        res.resize(max(a.size(),b.size()));
        for(int i=0;i<b.size();i++) res[i]=(res[i]-b[i]+mod)%mod;
        return res;
    }
}
using namespace NTT;
const int N=200005;
int n,p,g;
int a[N];
int ind[N];//指标
int get_gen(int m)
{
    //if(!check(m)) return ;
    int phip=m-1;//m为质数的情况是m-1,否则需要求phi(m)
    for(int gen=2;;gen++)
    {
        if(__gcd(gen,m)!=1) continue;
        int t=phip;
        bool ok=true;
        for(int i=2;i<=t/i;i++)
        {
            if(t%i==0)
            {
                if(qmi(gen,phip/i,m)==1)
                {
                    ok=false;
                    break;
                }
                while(t%i==0) t/=i;
            }
        }
        if(t!=1&&qmi(gen,phip/t,m)==1) ok=false;

        if(ok) return gen%m;
    }
}
void solve()
{
    scanf("%d%d",&n,&p);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    if(p==1)
    {
        puts("1 1");
        puts("0");
        return ;
    }
    else if(p==2)
    {
        int maxi=-1;
        vector<int> pathc;
        for(int c=0;c<p;c++)
        {
            vector<bool> st(3);
            for(int i=1;i<=n;i++)
            {
                st[a[i]]=true;
            }
            int mex=0;
            while(st[mex]) mex++;
            if(mex>maxi) maxi=mex,pathc.clear();
            if(mex==maxi) pathc.push_back(mex);
        }
        printf("%d %d\n",pathc.size(),maxi);
        for(auto c:pathc) printf("%d ",c);
        puts(""); 
        return ;
    }
    bool no_zero=true;
    for(int i=1;i<=n;i++) if(!a[i]) no_zero=false;
    if(no_zero)
    {
        puts("1 1");
        puts("0");
        return ;
    }
    g=get_gen(p);
    for(int i=0;i<p-1;i++) ind[qmi(g,i,p)]=i;//下标1~p-1分别对应的指标0~p-2
    Poly B(p-1);
    for(int i=1;i<=n;i++)
    {
        if(a[i]==0) continue;
        int t=ind[a[i]];
        B[t]=1;
    }
    reverse(B.begin(),B.end());
    vector<int> pathc;
    auto check=[&](int mid){
        if(mid==0)
        {
            return true;
        }
        Poly A(p-1);
        for(int i=1;i<=mid;i++) A[ind[i]]=1;//1~mex-1对应的指标
        Poly res=A*B;
        pathc.clear();
        //j-i+p-1 j-i=>x
        for(int i=0;i<p-1;i++) res[i]+=res[i+p-1];
        for(int i=0;i<p-1;i++)
        {
            if(res[i]==mid)
            {
                pathc.push_back(p-2-i);
            }
        }
        return pathc.size()!=0;
    };
    int l=0,r=p-1;
    while(l<r)//二分mex-1是否可行
    {
        int mid=l+r+1>>1;
        if(check(mid)) l=mid;
        else r=mid-1;
    }
    check(l);
    int mex=l+1;
    for(auto &c:pathc) c=qmi(g,c,p);
    if(mex==1) pathc.push_back(0);
    sort(pathc.begin(),pathc.end());
    printf("%d %d\n",pathc.size(),mex);
    for(auto c:pathc) printf("%d ",c);
    puts("");
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
}

詳細信息

Test #1:

score: 100
Accepted
time: 2ms
memory: 5636kb

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
Wrong Answer
time: 2ms
memory: 5708kb

input:

3
1 2
0
1 2
1
2 2
1 0

output:

2 1
1 1 
2 0
0 0 
2 2
2 2 

result:

wrong answer 2nd lines differ - expected: '0 1', found: '1 1 '