100027. 【NOIP2017提高A组模拟7.7】表达式

题目描述

  • 求:
  • i = 1 k p i 2 p 1 m o d    p 2 \sum_{i=1}^{kp}i^{2p-1} \mod p^2
  • 其中p为质数
  • 1 k , p 1 0 9 1 \le k,p \le 10^9

题目描述

其中最关键的是p是质数

方法一:

然后,“数论算个屁,打表找规律。” 就闪亮登场了!

首先我们枚举k与p,然后得出了以下的规律:
p=2,答案序列为:1,0,1,0,1,0,1,0,1,0,1,0…
p=3,答案序列为:6,6,0,6,6,0,6,6,0,6,6,0…
p=5,答案序列为:15,10,10,15,0,15,10,10,15,0…
p=7,答案序列为:28,14,7,7,14,28,0,28,14,7,7,14,28,0…
p=11,答案序列为:66,22,110,88,77,77,88,110,22,66,0…

由此,我们可以3个规律:
1.答案序列有循环节,且长度为p
2.每一个循环节都是回文的(0除外)
3.每一个数都可以被p整除

可即使这样,我们还是不能发现个所以然,所以我们还要简化。
这时,我们通过规律3,给每一个数除p
注:我们去掉p=2(因为太特殊),然后让循环节的回文串折半
p=3:2
p=5:3,2
p=7:4,2,1
p=11:6,2,10,8,7

只要对数字有点敏感的人,都可以看得出来,后一项与前一项的差,是一个等差数列!(当然,是在 m o d    p \mod p 意义下)

于是乎,我们便可以@#¥@¥#@%@#¥@#¥,AC!

方法二:

好吧,我们来一点正常点的方法。

首先,我们来证明一个式子:
i = 1 p 1 i 2 p 1 p ( p + 1 ) 2 ( m o d    p 2 ) \sum_{i=1}^{p-1}i^{2p-1} \equiv \frac {p(p+1)}{2}(\mod p^2)
我们来推一波
如果此式子是正确的,则:
i = 1 p 1 [ i 2 p 1 + ( p i ) 2 p 1 ] p ( p + 1 ) ( m o d     2 p ) \sum_{i=1}^{p-1}[i^{2p-1}+(p-i)^{2p-1}] \equiv p(p+1)(\mod ^2p)

i = 1 p 1 [ i 2 p 1 + ( 2 p 1 ) p i 2 p 2 i 2 p 1 ] p ( p + 1 ) ( m o d    p 2 ) \sum_{i=1}^{p-1}[i^{2p-1}+(2p-1)pi^{2p-2}-i^{2p-1}] \equiv p(p+1)(\mod p^2)

i = 1 p 1 ( 2 p 1 ) p i 2 p 2 p ( p + 1 ) ( m o d    p 2 ) \sum_{i=1}^{p-1}(2p-1)pi^{2p-2} \equiv p(p+1)(\mod p^2)

i = 1 p 1 ( 2 p 1 ) i 2 p 2 ( p + 1 ) ( m o d    p ) \sum_{i=1}^{p-1}(2p-1)i^{2p-2} \equiv (p+1)(\mod p)

i = 1 p 1 ( 2 p 1 ) ( p + 1 ) ( m o d    p ) \sum_{i=1}^{p-1}(2p-1) \equiv (p+1)(\mod p)

( p 1 ) ( 2 p 1 ) 1 ( m o d    p ) (p-1)(2p-1) \equiv 1(\mod p)

1 1 ( m o d    p ) 1 \equiv 1(\mod p)

接着让我们来看一下原来的式子:
i = 1 k p i 2 p 1 m o d    p 2 \sum_{i=1}^{kp}i^{2p-1} \mod p^2
让我们继续去推一波
i = 0 k 1 j = 1 p ( i p + j ) 2 p 1 m o d    p 2 \sum_{i=0}^{k-1}\sum_{j=1}^{p}(ip+j)^{2p-1} \mod p^2

i = 0 k 1 j = 1 p 1 ( i p + j ) 2 p 1 m o d    p 2 \sum_{i=0}^{k-1}\sum_{j=1}^{p-1}(ip+j)^{2p-1} \mod p^2

i = 0 k 1 j = 1 p 1 j 2 p 1 + ( 2 p 1 ) i p j 2 p 2 m o d    p 2 \sum_{i=0}^{k-1}\sum_{j=1}^{p-1}j^{2p-1}+(2p-1)ipj^{2p-2} \mod p^2

k p ( p + 1 ) 2 + i = 0 k 1 j = 1 p 1 ( 2 p 1 ) i p j 2 p 2 m o d    p 2 \frac {kp(p+1)}{2}+\sum_{i=0}^{k-1}\sum_{j=1}^{p-1}(2p-1)ipj^{2p-2} \mod p^2

k p ( p + 1 ) 2 + i = 0 k 1 i j = 1 p 1 ( 2 p 1 ) p j 2 p 2 m o d    p 2 \frac {kp(p+1)}{2}+\sum_{i=0}^{k-1}i*\sum_{j=1}^{p-1}(2p-1)pj^{2p-2} \mod p^2

到了这一步,我们便陷入了瓶颈,怎么化简呢?
别着急,我们看一看在证明引理的时候,我们的一行证明。
i = 1 p 1 ( 2 p 1 ) p i 2 p 2 p ( p + 1 ) ( m o d    p 2 ) \sum_{i=1}^{p-1}(2p-1)pi^{2p-2} \equiv p(p+1)(\mod p^2)
再看看
j = 1 p 1 ( 2 p 1 ) p j 2 p 2 m o d    p 2 \sum_{j=1}^{p-1}(2p-1)pj^{2p-2} \mod p^2
是不是很interesting!让我们来继续化简
k p ( p + 1 ) 2 + i = 0 k 1 i p ( p + 1 ) m o d    p 2 \frac {kp(p+1)}{2}+\sum_{i=0}^{k-1}i*p(p+1) \mod p^2

k p ( p + 1 ) 2 + i = 0 k 1 i p m o d    p 2 \frac {kp(p+1)}{2}+\sum_{i=0}^{k-1}i*p \mod p^2

k p ( p + 1 ) 2 + k ( k 1 ) 2 p m o d    p 2 \frac {kp(p+1)}{2}+\frac {k(k-1)}{2}*p \mod p^2

然后就解出来了!
时间复杂度:O(1)(明显的

代码(这里只给“打表”法)

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int main()
{
	ll k,p;scanf("%lld%lld",&k,&p);
	k%=p;
	if(k==0) printf("0\n");
	else{
		if(p-k<k) k=p-k;
		ll st=p-(p-1)/2,ed=p-(p-1)/2+k-1;
		ll t=((st+ed)*k/2)%p;
		printf("%lld\n",t*p);
	}
	return 0;
}
发布了58 篇原创文章 · 获赞 12 · 访问量 8571

猜你喜欢

转载自blog.csdn.net/fengqiyuka/article/details/82953717
今日推荐