AGC 047 C 题解

AGC 047 C 题解

一个数论好题

可以发现P是一个NTT模数,原根是2。

则任何一个<P的数都可以表示成\(2^x\mod p\)

两个数相乘也就可以表示成\(2^x\times 2^y=2^{(x+y)\mod (p-1)}\)

直接fft就好了。

/*
{
######################
#       Author       #
#        Gary        #
#        2021        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
typedef complex<double> Comp;
const double PI=3.14159265358979323846;
const Comp I(0,1);
const int len=1<<19;
int rev[len];
void butterfly(vector<Comp> & v){
	rep(i,len){
		rev[i]=rev[i>>1]>>1;
		if(i&1) rev[i]|=len>>1; 
	}
	rep(i,len) if(rev[i]>i) swap(v[i],v[rev[i]]);
}
vector<Comp> fft(vector<Comp> v,int ty){
	butterfly(v);
	vector<Comp> nex;
	for(int l=2;l<=len;l<<=1){
		nex.clear();
		nex.resize(len);
		Comp step(cos(2.0*PI/l),sin(2.0*ty*PI/l));
		for(int j=0;j<len;j+=l){
			Comp now(1,0);
			for(int k=0;k<l/2;++k){
				Comp A,B;
				A=v[j+k];
				B=v[j+l/2+k];
				B=now*B;
				nex[j+k]=A+B;
				nex[j+k+l/2]=A-B;
				now=now*step;
			}
		}
		v=nex;
	}
	return v;
}
const int MOD=200003;
const int g=2;
int is[MOD],pow_[MOD];
vector<Comp> v(len);
LL cnt[len];
int main(){
	int now=1;
	rb(i,0,MOD-2){
		is[now]=i;
		pow_[i]=now;
		now<<=1;
		now%=MOD;
	}
	vector<int> a;
	LL rest=0;
	int n;
	scanf("%d",&n);
	rb(i,1,n){
		int ai;
		scanf("%d",&ai);
		if(ai){
			a.PB(ai);
			cnt[is[ai]]++;
		}
	}
	n=a.size();
	rep(i,len) v[i]=Comp(cnt[i],0);
	v=fft(v,1);
	rep(i,len) v[i]*=v[i];
	v=fft(v,-1);
	rep(i,len) cnt[i]=floor((v[i].real()/len)+0.5);
	rb(i,0,MOD-2){
		cnt[i]+=cnt[i+MOD-1];
		rest+=1ll*pow_[i]*cnt[i];
	}
	rep(i,n)
		rest-=1ll*a[i]*a[i]%MOD;
	cout<<rest/2<<endl;
	return 0;
}

posted @ 2021-01-03 15:50  WWW~~~  阅读(78)  评论(0编辑  收藏  举报