QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#202412 | #6399. Classic: Classical Problem | ucup-team870 | WA | 1ms | 10012kb | C++20 | 4.7kb | 2023-10-06 01:20:46 | 2023-10-06 01:20:47 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define IOS {cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);}
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define P pair<int,int>
#define ll long long
#define vi vector<int>
#define db double
const int N=2e5+5;
namespace MTT { //任意模数多项式乘法. 无需long double
typedef vi poly;
int mod; const db pi = acos(-1.0);
struct cp {
db r, i;
cp() {}
cp(const db& _r, const db& _i) :r(_r), i(_i) {}
};
inline cp operator + (const cp& a, const cp& b) { return cp(a.r + b.r, a.i + b.i); }
inline cp operator - (const cp& a, const cp& b) { return cp(a.r - b.r, a.i - b.i); }
inline cp operator * (const cp& a, const cp& b) { return cp(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r); }
inline cp operator / (const cp& a, const db& b) { return cp(a.r / b, a.i / b); }
inline cp conj(const cp& a) { return cp(a.r, -a.i); }
int rev[N * 4]; cp Wn[N * 4]; int Now_Len;
inline void revinit(int n) {
for (int i = 0; i < n; ++i)rev[i] = (rev[i >> 1] >> 1) | ((i & 1) * (n >> 1));
for (int i = 0; i < n; ++i)Wn[i] = cp(cos(pi * i / n), sin(pi * i / n));
Now_Len = n;
}
inline void DFT(cp* A, int n) {
if (Now_Len != n)revinit(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) {
cp u = A[j + k], v = A[i + j + k] * Wn[n / i * k];
A[j + k] = u + v; A[i + j + k] = u - v;
}
}
}
}
inline void IDFT(cp* A, int n) {
if (Now_Len != n)revinit(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) {
cp u = A[j + k], v = A[i + j + k] * conj(Wn[n / i * k]);
A[j + k] = u + v;
A[i + j + k] = u - v;
}
}
}
for (int i = 0; i < n; ++i)A[i] = A[i] / n;
}
cp Ta[N * 4], Tb[N * 4], Tc[N * 4], Td[N * 4];
poly MTT(const poly& A,const poly& B) {
int lenA = A.size(), lenB = B.size();
int lenC = lenA + lenB - 1, n;
for (n = 1; n < lenC; n <<= 1);
poly C(n);
for (int i = 0; i < lenA; ++i)Ta[i] = cp(A[i] & 32767, A[i] >> 15);
for (int i = 0; i < lenB; ++i)Tb[i] = cp(B[i] & 32767, B[i] >> 15);
for (int i = lenA; i < n; ++i)Ta[i] = cp(0, 0);
for (int i = lenB; i < n; ++i)Tb[i] = cp(0, 0);
DFT(Ta, n); DFT(Tb, n);
for (int i = 0; i < n; ++i) {
int j = (n - i) & (n - 1);
cp A0 = (Ta[i] + conj(Ta[j])) * cp(0.5, 0);
cp A1 = (Ta[i] - conj(Ta[j])) * cp(0, -0.5);
cp B0 = (Tb[i] + conj(Tb[j])) * cp(0.5, 0);
cp B1 = (Tb[i] - conj(Tb[j])) * cp(0, -0.5);
Tc[i] = A0 * B0 + A0 * B1 * cp(0, 1);
Td[i] = A1 * B0 + A1 * B1 * cp(0, 1);
}
IDFT(Tc, n); IDFT(Td, n);
for (int i = 0; i < n; ++i) {
ll s1 = (ll)(Tc[i].r + 0.5) % mod;
ll s2 = (ll)(Tc[i].i + 0.5) % mod;
ll s3 = (ll)(Td[i].r + 0.5) % mod;
ll s4 = (ll)(Td[i].i + 0.5) % mod;
C[i] = (s1 + ((s2 + s3) << 15) + (s4 << 30)) % mod;
}
return C;
}
};
void slv(){
int n,p;cin>>n>>p;
vi pw(p+1),lg(p+1); int g=-1;
auto ok=[&](int g){
pw[0]=pw[p-1]=1;
rep(i,1,p-2){
pw[i]=1ll*pw[i-1]*g%p; if(pw[i]==1)return false;
}
rep(i,0,p-2)lg[pw[i]]=i;
return true;
};
rep(i,1,p-1){
if(ok(i)){g=i;break;}
}
assert(g!=-1); //p=2时g=1
vi a(n+1),b(p-1);
int fl=0;
rep(i,1,n){
cin>>a[i]; if(a[i]==0)fl=1;
}
if(!fl){
cout<<"1 1\n0\n";return;
}
if(n==1){
cout<<p<<" 1\n";
rep(i,0,p-1)cout<<i<<' '; cout<<'\n';
return;
}
rep(i,1,n){
if(a[i]==0)continue;
b[(p-1-lg[a[i]])%(p-1)]=1;
}
// for(auto v:b)cout<<v<<' '; cout<<'\n';
vi ans;
auto ck=[&](int res){
vi c(p-1);
rep(i,1,res)c[lg[i]]=1;
MTT::mod=p;
vi d=MTT::MTT(b,c);
// cout<<res<<":\n";
// for(auto v:b)cout<<v<<' '; cout<<'\n';
// for(auto v:c)cout<<v<<' '; cout<<'\n';
// for(auto v:d)cout<<v<<' '; cout<<'\n';
ans.clear();
rep(i,0,(int)d.size()-1){
if(d[i]==res)ans.push_back(pw[i%(p-1)]);
}
return ans.size()>0;
};
int l=1,r=p-1;
while(l<=r){
int mid=l+r>>1;
if(ck(mid))l=mid+1;
else r=mid-1;
}
ck(l-1);
sort(ans.begin(),ans.end());
ans.resize(unique(ans.begin(),ans.end())-ans.begin());
cout<<ans.size()<<' '<<l<<'\n';
for(auto v:ans)cout<<v<<' '; cout<<'\n';
}
signed main(){
IOS
int T;cin>>T;
while(T--)slv();
}
/*
1
3 5
0 2 3
*/
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 9948kb
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: 0
Accepted
time: 0ms
memory: 9816kb
input:
3 1 2 0 1 2 1 2 2 1 0
output:
2 1 0 1 1 1 0 1 2 1
result:
ok 6 lines
Test #3:
score: -100
Wrong Answer
time: 1ms
memory: 10012kb
input:
7 1 3 0 1 3 1 2 3 1 0 1 3 2 2 3 2 0 2 3 1 2 3 3 0 1 2
output:
3 1 0 1 2 1 1 0 1 2 1 1 1 0 1 2 2 1 1 0 1 3 2
result:
wrong answer 13th lines differ - expected: '2 3', found: '1 3'