QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#104024 | #6399. Classic: Classical Problem | He_Ren# | WA | 15ms | 13108kb | C++14 | 3.5kb | 2023-05-08 11:16:29 | 2023-05-08 11:16:31 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN = 2e5 + 5;
const int mod = 998244353;
inline void add_mod(int &a,int b){ a+=b; if(a>=mod) a-=mod;}
inline ll pw(ll a,ll b,int p = mod)
{
ll res = 1;
while(b)
{
if(b&1) res=res*a%p;
a=a*a%p; b>>=1;
}
return res;
}
namespace Poly
{
const int g = 3;
const int N = 1<<21;
int omega[N+5];
inline void init(void)
{
omega[0] = 1; omega[1] = pw(g, (mod-1) / N);
for(int i=2; i<N; ++i) omega[i] = (ll)omega[i-1] * omega[1] %mod;
}
inline void dft(int a[],int n)
{
for(int i=0,j=0; i<n; ++i)
{
if(i<j) swap(a[i],a[j]);
for(int k=n>>1; (j^=k)<k; k>>=1);
}
for(int k=1, step=N>>1; k<n; k<<=1, step>>=1)
for(int i=0; i<n; i+=k<<1)
for(int j=i, cur=0; j<i+k; ++j, cur+=step)
{
int tmp = (ll)a[j+k] * omega[cur] %mod;
add_mod(a[j+k] = a[j], mod - tmp); add_mod(a[j], tmp);
}
}
inline void idft(int a[],int n){ dft(a,n); reverse(a+1,a+n);}
int a[N+5], b[N+5];
inline vector<int> mul(const vector<int> &A,const vector<int> &B)
{
if(!A.size() || !B.size()) return vector<int>();
vector<int> res((int)A.size() + (int)B.size() - 1);
int n = 1;
while(n < (int)res.size()) n<<=1;
for(int i=0; i<n; ++i) a[i] = i<(int)A.size()? A[i]: 0;
for(int i=0; i<n; ++i) b[i] = i<(int)B.size()? B[i]: 0;
dft(a,n); dft(b,n);
for(int i=0; i<n; ++i) a[i] = (ll)a[i] * b[i] %mod;
idft(a,n);
ll invn = pw(n,mod-2);
for(int i=0; i<(int)res.size(); ++i) res[i] = a[i] * invn %mod;
return res;
}
} using Poly::mul;
vector<int> getfact(int p)
{
vector<int> res;
for(int i=2; (ll)i*i<=p; ++i)
if(p%i == 0)
{
res.emplace_back(i);
while(p%i == 0) p /= i;
}
if(p > 1) res.emplace_back(p);
return res;
}
int getrt(int p)
{
auto fact = getfact(p-1);
for(int i=1; i<p; ++i)
{
bool flag = 1;
for(auto t: fact)
if(pw(i, (p - 1) / t) == 1)
{
flag = 0;
break;
}
if(flag) return i;
}
return -1;
}
int a[MAXN];
void solve(void)
{
int n,p;
scanf("%d%d",&n,&p);
for(int i=1; i<=n; ++i)
scanf("%d",&a[i]);
sort(a+1, a+n+1);
if(a[1] != 0)
{
printf("1 1\n");
printf("0\n");
return;
}
if(n == 1)
{
printf("%d 1\n",p);
for(int i=0; i<p; ++i)
printf("%d ",i);
printf("\n");
return;
}
int g = getrt(p);
static int val[MAXN];
val[0] = -1;
for(int i=0,j=1; i<p-1; ++i)
{
val[j] = i;
j = (ll)j * g % p;
}
// printf("g = %d\n",g);
// for(int i=1; i<p; ++i)
// printf("val[%d] = %d\n",i,val[i]);
vector<int> res;
auto chk = [&] (int k) -> bool
{
if(k > p-1) return 0;
vector<int> A(p-1), B(p);
for(int i=2; i<=n; ++i)
A[val[i]] = 1;
for(int i=1; i<=k; ++i)
B[p-1-val[i]] = 1;
res = mul(A, B);
for(int i=p-1; i<(int)res.size(); ++i)
res[i % (p-1)] += res[i];
res.resize(p-1);
for(int i=0; i<p-1; ++i)
if(res[i] >= k)
return 1;
return 0;
};
int l = 1, r = p-1;
while(l<r)
{
int mid = (l+r+1)>>1;
if(chk(mid)) l=mid;
else r=mid-1;
}
chk(l);
vector<int> fin;
for(int i=2; i<=n; ++i)
if(res[val[a[i]]] >= l)
{
fin.emplace_back(pw(a[i], p-2, p));
}
sort(fin.begin(), fin.end());
printf("%d %d\n",(int)fin.size(),l+1);
for(auto t: fin)
printf("%d ",t);
printf("\n");
}
int main(void)
{
Poly::init();
int T;
scanf("%d",&T);
while(T--) solve();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 13108kb
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: 10ms
memory: 12920kb
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: 15ms
memory: 12056kb
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 0 2 1 1 0 1 2 2 1 1 0 2 3 1 2
result:
wrong answer 5th lines differ - expected: '1 2', found: '0 2'