QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#241671#6399. Classic: Classical Problemucup-team902#WA 4ms107420kbC++144.3kb2023-11-06 15:30:482023-11-06 15:30:48

Judging History

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

  • [2023-11-06 15:30:48]
  • 评测
  • 测评结果:WA
  • 用时:4ms
  • 内存:107420kb
  • [2023-11-06 15:30:48]
  • 提交

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 1\n", p);
        for(int i = 0; i < p; ++i){
            printf("%d%c", i, " \n"[i == p - 1]);
        }
        return ;
    }
    memset(vis, 0, p << 2);
    int g = 0;
    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;
        }
    }
    assert(g);
    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: 3ms
memory: 107420kb

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: 106536kb

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: 0
Accepted
time: 4ms
memory: 106776kb

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
2 3
1 2

result:

ok 14 lines

Test #4:

score: -100
Wrong Answer
time: 0ms
memory: 106544kb

input:

31
1 5
0
1 5
1
2 5
1 0
1 5
2
2 5
0 2
2 5
2 1
3 5
1 0 2
1 5
3
2 5
0 3
2 5
1 3
3 5
0 1 3
2 5
3 2
3 5
0 2 3
3 5
2 1 3
4 5
2 0 1 3
1 5
4
2 5
4 0
2 5
1 4
3 5
1 4 0
2 5
2 4
3 5
2 4 0
3 5
4 2 1
4 5
1 0 4 2
2 5
4 3
3 5
0 4 3
3 5
3 1 4
4 5
1 4 3 0
3 5
4 3 2
4 5
2 4 0 3
4 5
2 1 4 3
5 5
1 3 0 2 4

output:

5 1
0 1 2 3 4
1 1
0
1 2
1
1 1
0
1 2
2
1 1
0
1 3
1
1 1
0
1 2
3
1 1
0
1 3
3
1 1
0
2 2
2 3
1 1
0
1 4
1
1 1
0
1 2
4
1 1
0
2 2
1 4
1 1
0
1 3
2
1 1
0
1 4
2
1 1
0
1 3
4
1 1
0
1 4
3
1 1
0
1 4
4
1 1
0
4 5
1 2 3 4

result:

wrong answer 10th lines differ - expected: '3', found: '2'