因为给定的模数P保证是素数,所以P一定有原根.

根据原根的性质,若\(g\)是\(P\)的原根,则\(g^k\)能够生成\([1,P-1]\)中所有的数,这样的k一共有P-2个.

则\(a_i*a_j(mod\ P)=a_k\) 就可以转化为\(g^i*g^j(mod\ P) = g^{i+j}(mod\ P)=g^k\).

问题转化为了求有多少对有序的<i,j>满足 \((i+j)(mod\ (P-1)) = k\).

求出原根后,对\([1,P-1]\)中的每个数编号, 统计每个编号出现的次数,然后FFT求卷积

要特判0,因为原根不会生成0.所以用总的有序对数-其他不含0的有序对数得到含0的有序对,这是0的答案;超过P-1的数肯定没有符合的有序对.

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5+5;
bool notpri[maxn];
int pri[maxn],zyz[maxn];
typedef long long LL; void pre(int N){
notpri[1]=1;
for(int i=2;i<N;++i){
if(!notpri[i]){
pri[++pri[0]]=i;
}
for(int j=1;j<=pri[0] && (LL)i*(LL)pri[j]<N;++j){
notpri[i*pri[j]]=1;
if(i%pri[j]==0){
break;
}
}
}
}
LL Quick_Pow(LL x,LL p,LL mod){
if(!p){
return 1ll;
}
LL res=Quick_Pow(x,p>>1,mod);
res=res*res%mod;
if((p&1ll)==1ll){
res=(x%mod*res)%mod;
}
return res;
}
int FindRoot(int x){/*求素奇数的最小原根,倘若x不是奇数,但是也有原根的话,将质
因子分解改成对phi(x)即可。倘若要求多个原根,直接接着暴力验证即可*/
int tmp=x-1;
for(int i=1;tmp && i<=pri[0];++i){
if(tmp%pri[i]==0){
zyz[++zyz[0]]=pri[i];
while(tmp%pri[i]==0){
tmp/=pri[i];
}
}
}
for(int g=2;g<=x-1;++g){
bool flag=1;
for(int i=1;i<=zyz[0];++i){
if(Quick_Pow((LL)g,(LL)((x-1)/zyz[i]),(LL)x)==1){
flag=0;
break;
}
}
if(flag){
return g;
}
}
return 0;
} const int MAXN = 4e5 + 10;
const double PI = acos(-1.0);
struct Complex{
double x, y;
inline Complex operator+(const Complex b) const {
return (Complex){x +b.x,y + b.y};
}
inline Complex operator-(const Complex b) const {
return (Complex){x -b.x,y - b.y};
}
inline Complex operator*(const Complex b) const {
return (Complex){x *b.x -y * b.y,x * b.y + y * b.x};
}
} va[MAXN * 2 + MAXN / 2], vb[MAXN * 2 + MAXN / 2];
int lenth = 1, rev[MAXN * 2 + MAXN / 2];
int N, M; // f 和 g 的数量
//f g和 的系数
// 卷积结果
// 大数乘积
int f[MAXN],g[MAXN];
vector<LL> conv;
vector<LL> multi;
//f g
void init()
{
int tim = 0;
lenth = 1;
conv.clear(), multi.clear();
memset(va, 0, sizeof va);
memset(vb, 0, sizeof vb);
while (lenth <= N + M - 2)
lenth <<= 1, tim++;
for (int i = 0; i < lenth; i++)
rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (tim - 1));
}
void FFT(Complex *A, const int fla)
{
for (int i = 0; i < lenth; i++){
if (i < rev[i]){
swap(A[i], A[rev[i]]);
}
}
for (int i = 1; i < lenth; i <<= 1){
const Complex w = (Complex){cos(PI / i), fla * sin(PI / i)};
for (int j = 0; j < lenth; j += (i << 1)){
Complex K = (Complex){1, 0};
for (int k = 0; k < i; k++, K = K * w){
const Complex x = A[j + k], y = K * A[j + k + i];
A[j + k] = x + y;
A[j + k + i] = x - y;
}
}
}
}
void getConv(){ //求多项式
init();
for (int i = 0; i < N; i++)
va[i].x = f[i];
for (int i = 0; i < M; i++)
vb[i].x = g[i];
FFT(va, 1), FFT(vb, 1);
for (int i = 0; i < lenth; i++)
va[i] = va[i] * vb[i];
FFT(va, -1);
for (int i = 0; i <= N + M - 2; i++)
conv.push_back((LL)(va[i].x / lenth + 0.5));
} LL vz[MAXN];
int id[MAXN];
int cnt[MAXN];
int rnk[MAXN];
LL ans[MAXN]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
pre(maxn-1);
int n,P ;
scanf("%d %d",&n, &P);
int rt = FindRoot(P);
memset(id,0,sizeof(id)); LL idx = 1;
for(int i=0;i<P-1;++i){ //一共只有[0,P-2],P-1个id
id[idx] = i;
rnk[i]= idx;
idx = idx*rt%P;
} for(int i=1;i<=n;++i){
LL tmp;
scanf("%lld",&tmp);
vz[i] = tmp;
tmp%=P;
if(tmp==0) continue; //卷积中不考虑0的贡献
cnt[id[tmp]]++;
} N = M = P;
for(int i=0;i<P-1;++i){
f[i] = g[i] = cnt[i];
} getConv();
int sz = conv.size(); for(int i=0;i<sz;++i){
LL tmp = conv[i];
ans[rnk[i%(P-1)]] += tmp;
} LL tot = (LL)n*n; //全部的枚举可能-不选0之外的组合 = 包含0的组合
for(int i=1;i<P;++i){
tot -= ans[i];
}
ans[0] = tot;
for(int i=1;i<=n;++i){
if(vz[i]>=P) printf("0\n");
else{
printf("%lld\n",ans[vz[i]]);
}
}
return 0;
}

2018秦皇岛ccpc-camp Steins;Gate (原根+FFT)的更多相关文章

  1. 秦皇岛winter camp 总结

    冬令营在秦皇岛自闭了七天,很多题目看了都没有思路,或者是不知道怎么敲代码.我发现图论的题,自己连怎么建树都给忘了,想了半天.还有很多自己从未接触过的算法.在说说课堂上课的情况,大部分时间都是全程懵逼的 ...

  2. UOJ#449. 【集训队作业2018】喂鸽子 min-max容斥,FFT

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ449.html 题解 设 f(i) 表示给 i 只鸽子喂食使得至少一只鸽子被喂饱的期望次数,先 min-max容斥 一下. ...

  3. 2018.12.31 bzoj3771: Triple(生成函数+fft+容斥原理)

    传送门 生成函数经典题. 题意简述:给出nnn个数,可以从中选1/2/31/2/31/2/3个,问所有可能的和对应的方案数. 思路: 令A(x),B(x),C(x)A(x),B(x),C(x)A(x) ...

  4. 2019 秦皇岛CCPC赛后总结

    以前一直想参加ICPC或CCPC的,所以即使得知比赛会打星号,我还是想去. 感觉自己对什么都没有兴趣了,比较渴望找点快乐.. 这场比赛非常强,吉老师和杜老师都来啦,还有岛娘! 有幸要到了签名 滚榜的时 ...

  5. 牛客国庆训练,CCPC Camp DAY1 J 倍增,括号匹配

    https://www.nowcoder.com/acm/contest/201#question 题意:中文不翻译了 解法的个人理解: 对于一个合法的区间$[L,R]$ 1.显然其左括号的匹配位置都 ...

  6. 秦皇岛CCPC的失败总结

    个人状态原因:尤其是我,在比赛前没有很好的做准备,还一直看小说,前两天我们本来应该好好打两场训练赛的时候却没有打,然后一直在玩手机,比赛前一天,我下午就不小心睡着了,然后晚上醒来睡不着第二天的精神状态 ...

  7. 2017 秦皇岛CCPC Balloon Robot (ZOJ 3981)

    题意:给出n个队伍,m个座位,q次A题的队伍与时间,下一行是n个队伍的坐的位置,再下面q行就是第x个队再第y秒A出一道题,然后有一个机器人,开始位置由你选,他每走一步 他就会向右走一格,走到m的时候会 ...

  8. 2018 桂林ccpc现场赛 总结

    Day 0 5个小时的火车,坐的昏昏欲睡.桂林站出来没有地铁,而是出租车排成长队依次上车,也算是某种意义上的地铁吧.到了酒店才发现学校那边又给我们换了,又拖着行李找新的酒店,途中路过一家餐馆,所有人都 ...

  9. 2018 Wannafly summer camp Day8--连通块计数

    连通块计数 描述 题目描述: 小 A 有一棵长的很奇怪的树,他由 n 条链和 1 个点作为根构成,第 i条链有 ai​ 个点,每一条链的一端都与根结点相连. 现在小 A 想知道,这棵长得奇怪的树有多少 ...

随机推荐

  1. CImage类提供了GetBits()函数原理及实现

    CImage类提供了GetBits()函数来读取数据区,GetBits()函数返回的是图片最后一行第一个像素的地址,网上有人说返回指针的起始位置是不同的,有些图片返回的是左上角像素的地址,有些是左下角 ...

  2. 介绍MFC框架中涉及到的设计模式(二)

    接着上一篇<介绍MFC框架中涉及到的设计模式(一)>介绍 单例模式(Singleton Pattern) 单例模式是一种经常使用的软件设计模式.在它的核心结构中仅仅包括一个被称为单例类的特 ...

  3. 安装wampserver时提示丢失MSVCR110.dll

    安装Wampserver 2后启动的时候提示系统错误:MSVCR110.dll丢失. 在wampserver官网上有例如以下提示: 于是卸载原来的WAMPSERVER 2 ,在http://www.m ...

  4. Objective-C实用类和协议

    Objective-C实用类和协议 目录 概述 NSObject 概述 NSObject 协议<NSObject> 类NSObject 详细方法参考文档 实用操作 是否为某个类或其子类 是 ...

  5. 【BZOJ2067】[Poi2004]SZN 二分+树上贪心

    [BZOJ2067][Poi2004]SZN Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一 ...

  6. 【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法

    [BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须 ...

  7. Hibernate传递list参数的例子

    public Map<String, String> getAllFeedBack(Object[] obj){ Map<String, String> map = new H ...

  8. DOS和BAT批量提取修改文件名

    DOS命令窗口:开始-cmd-回车,进入DOS命令窗口 案例一.获取文件名 dir 1.输入"文件所在盘",回车,如: d: 2.输入"cd 文件夹位置",回车 ...

  9. git sourcetree忽略某些文件提交

    打开sourcetree 点击edit按钮,在文件中加入如下内容.*.iws*.iml*.iprtarget/.settings.project.classpath.externalToolBuild ...

  10. 研究php单例模式实现数据库类

    实现单例模式:单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例. 单例模式的逻辑:类里面声明一个静态的方法和变量,静态变量用 ...