题目大意:

设\(f(i)\)为使\((x+y)^i \equiv x^i (mod\ p)\)成立的(x,y)的对数。其中\(1 \leq x \leq p-1 , 1\leq y\leq m\),m,p给定且p是一个质数。求\(\sum_{i=1}^{p-1}i*f(i)\),p<=1e9+7,m<=p-1

思路

我们考虑用原根去代换x,y。

设g为p的一个原根,\(g^a\equiv x(mod \ p),g^b \equiv y(mod \ p)\)。

然后我们用\(g\)去代换\(x,y\)。\((g^a+g^b)^i\equiv g^{a*i}(mod\ p)\)然后我们在式子两边同时除一个\(g^{a*i}\)。得到\((1+g^{b-a})^i\equiv 1(mod\ p)\)

设\(1+g^{b-a}\equiv g^k(mod\ p)\)(因为原根的性质所以我们一定可以找到这样的k)。

此时原式为\(g^{k*i} \equiv 1(mod\ p)\)由费马小定理可以到到\(p-1 \mid k*i\)。

这就要求k为\(\frac{p-1}{gcd(p-1,i)}\)的倍数(即至少包含p-1所特有的因子)。由于\(0<k<p-1\),为什么k不能取0呢?因为$g^{b-a}不会为0,所以\(1+g^{b-1}> 1\)。

所以可以得到这样的k的数量是\(\frac{p-1}{\frac{p-1}{gcd(p-1,i)}}-1=gcd(p-1,i)-1\),这里因为k不能取0和p-1,所以要减1。

又因为\(1+g^{b-a} \equiv g^k(mod\ p)\)得\(g^b \equiv(g^k-1)*g^a (mod\ p)\),\(y\equiv x*(g^k-1)(mod\ p)\)。每有一个k,y对应一个x。所以对于一个y有\(gcd(p-1,i)-1\)个x对应。

所以可以得出\(f(i)=m*(gcd(p-1,i)-1)\)。

\(\sum_{i=1}^{p-1}i*f(i)\)

\(=m\sum_{i=1}^{p-1}i*gcd(p-1,i)-m*\frac{(p-1)*p}{2}\)

重点是如何求\(\sum_{i=1}^{p-1}i*gcd(p-1,i)\)。

\(\sum_{i=1}^{p-1}i*gcd(p-1,i)\)

显然d是p-1的约数

\(=\sum_{d\mid p-1}d\sum_{i=1}^{p-1}i*[gcd(p-1,i)==d]\)

\(=\sum_{d\mid p-1}d^2\sum_{i=1}^{\frac{p-1}{d}}i*[gcd(\frac{p-1}{d},i)==1]\)

然后有一个神奇的变换。

\(\sum_{i=1}^{t}i*[gcd(t,i)==1]=\frac{t*\varphi(t)+[t==1]}{2}\)

为什么?

令\(t=\frac{p-1}{d}\)就是\(\sum_{i=1}^{t}i*[gcd(t,i)==1]\)

其实就是求1到t中与t互质的数的和。

由更相减损术得若\(gcd(n,i)=1\)则\(gcd(n,n-i)=1\)

所以一个与\(t\)互质的数\(x\),\(t-x\)也与\(t\)互质。

所以与t互质的数成对出现,设这一对数为a,b,有\(a+b=t\)。

所以\(\sum_{i=1}^{t}i*[gcd(t,i)==1]=\frac{t*\varphi(t)+[t==1]}{2}\)

故原式可以化为

\(\sum_{d\mid p-1}d^2\sum_{i=1}^{\frac{p-1}{d}}i*[gcd(\frac{p-1}{d},i)==1]\)

\(=\sum_{d\mid p-1}d^2*\frac{\frac{p-1}{d}*\varphi(\frac{p-1}{d})+[\frac{p-1}{d}==1]}{2}\)

带回去求解即可。

复杂度?\(O(能过)\),因为求约数可以先扫出质数来优化,所以\(\sqrt{\frac{p}{lnp}}*\sqrt{p}=\sqrt{\frac{p^2}{lnp}}\)差不多两亿,不是很大。而且求欧拉函数是求p-1的约数的约数,一定比\(\sqrt{p}\)小,所以能过?

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define int long long
const int N=1001000;
const int mod=1e9+7;
bool book[N];
int prime[N],cnt,inv,T;
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
void pre_work(){
for(int i=2;i<=1000000;i++){
if(book[i]==0)prime[++cnt]=i;
for(int j=1;j<=cnt&&prime[j]*i<=1000000;j++){
book[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
int ksm(int x,int b){
int tmp=1;
while(b){
if(b&1)tmp=tmp*x%mod;
b>>=1;
x=x*x%mod;
}
return tmp;
}
int phi(int x){
int tmp=x;
int ans=x;
for(int i=1;i<=cnt&&prime[i]*prime[i]<=x;i++){
if(tmp%prime[i]==0){
ans=ans/prime[i]*(prime[i]-1);
while(tmp%prime[i]==0)tmp/=prime[i];
}
}
if(tmp>1)ans=ans/tmp*(tmp-1);
return ans;
}
int work(int x){
int tmp=0;
for(int i=1;i*i<=x;i++){
if(x%i==0){
int a=i*i%mod;
int b=x/i;
int c=phi(b);
int d=(b==1);
tmp=(tmp+a*(b*c%mod+d)%mod*inv%mod)%mod;
if(x/i>i){
int hh=x/i;
int a=hh*hh%mod;
int b=x/hh;
int c=phi(b);
int d=(b==1);
tmp=(tmp+a*(b*c%mod+d)%mod*inv%mod)%mod;
}
}
}
return tmp;
}
signed main(){
T=read();
pre_work();
inv=ksm(2,mod-2);
int now=0;
while(T--){
now++;
int m=read(),p=read();
int tmp=((m*work(p-1)%mod-m*(p-1ll)%mod*p%mod*inv%mod)%mod+mod)%mod;
printf("Case #%lld: %lld\n",now,tmp);
}
return 0;
}

HDU 6051 If the starlight never fade(原根+推式子)的更多相关文章

  1. HDU 6051 - If the starlight never fade | 2017 Multi-University Training Contest 2

    /* HDU 6051 - If the starlight never fade [ 原根,欧拉函数 ] | 2017 Multi-University Training Contest 2 题意: ...

  2. HDU 3802 矩阵快速幂 化简递推式子 加一点点二次剩余知识

    求$G(a,b,n,p) = (a^{\frac {p-1}{2}}+1)(b^{\frac{p-1}{2}}+1)[(\sqrt{a} + \sqrt{b})^{2F_n} + (\sqrt{a} ...

  3. 【hdu6051】If the starlight never fade

    Portal --> hdu6051 Solution ​ 神仙题qwq好吧我个人感觉是神仙题 ​​ 这题其实有一个比较野路子的做法..就是..打表观察..反正场上ckw大佬就是这样把这题A穿的 ...

  4. HDU 4870 Rating(概率、期望、推公式) && ZOJ 3415 Zhou Yu

    其实zoj 3415不是应该叫Yu Zhou吗...碰到ZOJ 3415之后用了第二个参考网址的方法去求通项,然后这次碰到4870不会搞.参考了chanme的,然后重新把周瑜跟排名都反复推导(不是推倒 ...

  5. hdu 1465:不容易系列之一(递推入门题)

    不容易系列之一 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  6. hdu 5646 DZY Loves Partition 二分+数学分析+递推

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5646 题意:将n分成k个正整数之和,要求k个数全部相同:并且这k个数的乘积最大为多少?结果mod 1e^9 ...

  7. 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】

    Pokémon GO Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU 2175 汉诺塔IX (递推)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2175 1,2,...,n表示n个盘子.数字大盘子就大.n个盘子放在第1根柱子上.大盘不能放在小盘上.  ...

  9. HDU 2077 汉诺塔IV (递推)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2077 还记得汉诺塔III吗?他的规则是这样的:不允许直接从最左(右)边移到最右(左)边(每次移动一定是 ...

随机推荐

  1. this self指针

    this 和 self指针 为函数提供了运行上下问:为函数提供了当前对象的其实地址,方便函数的对对象的访问.

  2. 什么是2.5D与3D编辑模式

    ZBrush®其实就是一个带有三维特性的二维软件,它不仅具有绘制二维图像的功能,而且也具有对三维物体进行编辑的功能,就是所谓的2.5D(Pixol技术). 学习ZBrush之前有必要了解一下2.5D的 ...

  3. Vue学习之路第一篇(学习准备)

    1.开发工具的选择 这个和个人的开发习惯有关,并不做强求,厉害的话用记事本也可以.但是我还是建议用人气比较高的编辑工具,毕竟功能比较全面,开发起来效率比较高. 我之前写前端一直用的是sublimete ...

  4. dataTable 动态列 二次加载

    需要把 列头和表格内容全部清空 if ($('#datatable').hasClass('dataTable')) { var dttable = $('#datatable').dataTable ...

  5. Node.js 指南(迁移到安全的Buffer构造函数)

    迁移到安全的Buffer构造函数 移植到Buffer.from()/Buffer.alloc() API. 概述 本指南介绍了如何迁移到安全的Buffer构造函数方法,迁移修复了以下弃用警告: 由于安 ...

  6. minicom不能连arm-linux开发板的问题终于解决了!

    前一段时间一直有个问题困扰着我,大概是一次重新编译过kernel之后, gentoo上的minicom就不能和windows和开发板通信了. 为了解决这个问题,我把glibc/kernel/minic ...

  7. vue项目中,如何对static文件夹下的静态文件添加时间戳,以达到清除缓存

    例如config.js文件是存放在static文件夹下,里面存放的是websocket信息,需要经常改动.改动了以后由于缓存信息,使其不生效,因此需要对引入的文件添加时间戳. 最新方法: 注意转义符的 ...

  8. [LeetCode] 242. 有效的字母异位词 valid-anagram(排序)

    注意这里字母异位词的定义是:字母类别及个数都要一样,只是排列顺序不同. class Solution(object): def isAnagram(self, s, t): ""& ...

  9. oracle 的交并差函数,intersect;union;minus。

    创建表并添加数据: --创建TABLE_A create table TABLE_A ( A ), B ) ); --给TABLE_A添加数据 insert into TABLE_A values(' ...

  10. java几种读写文件的方式

    java.io的几种读写文件的方式 一.java把这些不同来源和目标的数据都统一抽象为数据流. Java语言的输入输出功能是十分强大而灵活的. 在Java类库中,IO部分的内容是很庞大的,因为它涉及的 ...