QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#241660#6399. Classic: Classical Problemucup-team902#WA 8ms107888kbC++144.3kb2023-11-06 15:19:232023-11-06 15:19:23

Judging History

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

  • [2023-11-06 15:19:23]
  • 评测
  • 测评结果:WA
  • 用时:8ms
  • 内存:107888kb
  • [2023-11-06 15:19:23]
  • 提交

answer

#include<bits/stdc++.h>

using namespace std;

#define gc c=getchar()
#define ll long long

template<typename T>
inline void read(T &x){
    x=0;T k=1;char gc;
    while(!isdigit(c)){if(c=='-')k=-1;gc;}
    while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
}

struct comp{
	double r,i;
	comp():r(0),i(0){}
	comp(const double &_r,const double &_i):r(_r),i(_i){}
};

inline comp operator + (const comp &a,const comp &b){
	return comp(a.r+b.r,a.i+b.i);
}

inline comp operator - (const comp &a,const comp &b){
	return comp(a.r-b.r,a.i-b.i);
}

inline comp operator * (const comp &a,const comp &b){
	return comp(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);
}

inline comp operator / (const comp &a,const double &b){
	return comp(a.r/b,a.i/b);
}

inline comp conj(const comp &a){
	return comp(a.r,-a.i);
}

const double PI=acos(-1.0);
const int N=2e6+7;

int rev[N];
comp Wn[N];
inline void revinit(int n){
	for(int i=0;i<n;++i)rev[i]=(rev[i>>1]>>1)|((i&1)*(n>>1));
	Wn[0]=comp(1,0);
	Wn[1]=comp(cos(2*PI/n),sin(2*PI/n));
	for(int i=2;i<n;++i)Wn[i]=Wn[i-1]*Wn[1];
}

inline void DFT(comp *A,int n){
	for(int i=0;i<n;++i)if(i<rev[i])swap(A[i],A[rev[i]]);
	for(int i=1;i<n;i<<=1){
		for(int j=0;j<n;j+=i<<1){
			for(int k=0;k<i;++k){
				comp u=A[j+k],v=A[i+j+k]*Wn[n/(i<<1)*k];
				A[j+k]=u+v;
				A[i+j+k]=u-v;
			}
		}
	}
}

inline void IDFT(comp *A,int n){
	for(int i=0;i<n;++i)if(i<rev[i])swap(A[i],A[rev[i]]);
	for(int i=1;i<n;i<<=1){
		for(int j=0;j<n;j+=i<<1){
			for(int k=0;k<i;++k){
				comp u=A[j+k],v=A[i+j+k]*conj(Wn[n/(i<<1)*k]);
				A[j+k]=u+v;
				A[i+j+k]=u-v;
			}
		}
	}
	for(int i=0;i<n;++i){
		A[i]=A[i]/n;
	}
}

int a[N];
int lg[N];
int pw[N];
int vis[N];

comp s[N];
comp t[N];

void solve(){
    int n, p; read(n), read(p);
    bool haszero = 0;
    for(int i = 0; i < n; ++i){
        read(a[i]);
        if(a[i] == 0){
            haszero = 1;
            --i;
            --n;
        }
    }
    if(!haszero){
        puts("1 1");
        puts("0");
        return ;
    }
    if(n == 0){
        printf("%d\n 1", p);
        for(int i = 0; i < p; ++i){
            printf("%d%c", i, " \n"[i == p - 1]);
        }
        return ;
    }
    int g;
    for(g = 1; g < p; ++g){
        int prod = 1;
        bool bad = 0;
        for(int i = 0; i < p - 1; ++i){
            if(vis[prod] == g){
                bad = 1;
                break;
            }
            lg[prod] = i;
            pw[i] = prod;
            vis[prod] = g;
            prod = (ll)prod * g % p;
        }
        if(!bad){
            break;
        }
    }
    for(int i = 0; i < n; ++i){
        s[lg[a[i]]] = comp(1, 0);
    }
    for(int i = 0; i < p - 1; ++i){
        s[i + p - 1] = s[i];
    }
    int len = 1;
    while(len < (p - 1) * 3){
        len <<= 1;
    }
    revinit(len);
    DFT(s, len);
    int l = 1, r = n;
    pair<int, vector<int>> ans(-1, vector<int>());
    while(l <= r){
        int mid = (l + r) >> 1;
        for(int i = 0; i < len; ++i){
            t[i] = comp(0, 0);
        }
        for(int i = 1; i <= mid; ++i){
            t[p - 2 - lg[i]] = comp(1, 0);
        }
        DFT(t, len);
        for(int i = 0; i < len; ++i){
            t[i] = t[i] * s[i];
        }
        IDFT(t, len);
        bool found = 0;
        for(int i = 0; i < p - 1; ++i){
            if(round(t[i + p - 2].r) == mid){
                found = 1;
                break;
            }
        }
        if(found){
            ans.first = mid + 1;
            ans.second.clear();
            for(int i = 0; i < p - 1; ++i){
                if(round(t[i + p - 2].r) == mid){
                    ans.second.push_back(pw[i]);
                }
            }
            l = mid + 1;
        }
        else{
            r = mid - 1;
        }
    }
    for(int i = 0; i < len; ++i){
        s[i] = t[i] = comp(0, 0);
    }
    printf("%d %d\n", ans.second.size(), ans.first);
    sort(ans.second.begin(), ans.second.end());
    for(int i = 0; i < ans.second.size(); ++i){
        printf("%d%c", ans.second[i], " \n"[i + 1 == ans.second.size()]);
    }
}

int main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    int T; read(T);
    while(T--){
        solve();
    }
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 106940kb

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: 8ms
memory: 107888kb

input:

3
1 2
0
1 2
1
2 2
1 0

output:

2
 10 1
1 1
0
1 2
1

result:

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