3823: 定情信物【递推】【线性筛逆元】【带推导过程】

来源:互联网 发布:专业网络零售商的优势 编辑:程序博客网 时间:2024/04/30 04:23

**

Description

**

都说程序员找不到妹子,可是无人知晓,三生石上竟然还刻着属于小 E 的一笔。

那一天,小 E 穷尽毕生的积蓄,赠与了妹子一个非同寻常的定情信物。那是一个小

小的正方体,但透过它,可以看到过去,可以洞彻天机。

这份信物仿佛一只深邃的眼。当看透它看似简单的外表后,深邃的内心却最是可以

叩击人的灵魂的。不出所料,妹子果然被这个信物超越空间的美所吸引。

“易有太极,是生两仪,两仪生四象,四象生八卦。,八卦定吉凶,吉凶生大业。”

这句箴言在其上得到了完美的诠释。

是的,这正是一个超正方体。

小 E 告诉妹子,他的情意也如这份信物一样深厚。现在妹子想知道,小 E 对她的情

意究竟有几分?

我们知道,点动成线,线动成面,面动成体……即 n 维超立方体可看作由 n-1 维超

立方体沿垂直于它的所有的棱的方向平移得到的立体图形。

我们可以将点看作 0 维超立方体,将直线看作 1 维超立方体,将正方形看作 2 维超

立方体……依此类推。

任何一个 n 维超立方体(n>0)都是由低维的超立方体元素组成的:它的 n-1 维表面

是 n-1 维的超立方体,它的 n-2 维边缘是 n-2 维的超立方体,它的 n-3 维元素是 n-3 维的

超立方体……

小 E 对妹子的情意即为在他的定情信物——K 维超立方体中,含有每一维的元素个

数。由于元素个数可能较大,只需要输出它所包含的每一维元素个数模 P 后的异或和。


**

Input

**

两个整数 K、P,详见题目叙述。


**

Output

**

一个非负整数,表示小 E 的定情信物所包含的每一维元素个数模 P 后的异或和。注

意:异或和可能会大于 P。


**

Sample Input

**

input 1

3 7

Input 2

4 2333

Input 3

12 7723


**

Sample Output

**

Output1

3

Output 2

33

Output 3

360


**

Hint

**

对于样例2的解释:

一个三维超立方体含有 8 个零维元素、12 个一维元素、6 个二维元素、1 个三维

元素,模 7 后分别为 1,5,6,1,异或和为 1^5^6^1=3。


对于 100%的数据,N≤10^7,P 为 10^9 内的素数。


**

Solution

终于推出来了好开森QAQ

高维超方体第i维元素的数量将是原超方体第i维的数量*2+(i-1)维的数量

首先我们知道这个推导过程 但是复杂度是O(n2) 的显然我们无法承受= =

然后神犇们都说打表找规律……像我这么弱……打表也看不出规律啊……

于是就默默的推公式好了= =

刚开始并没有写成2x这种形式 而是把所有数都算出来了= =当然看不出了

之后发现了这个很好的性质 2x

然后就试着写了一些表格- -

我们用f[i][j]表示在 i. 维正方体j维元素的数量
边界条件f[i][i]=2=20=120是显然的

假设我们现在已知f[i][j]考虑对f[i+1][j] 的贡献是什么 ??

乘2了

所以不妨设f[i][j]=k2xf[i+1][j]的贡献就是k2x2=k2x+1
然后我们发现上下两行2x的系数差1

所以能得到式子f[i][n]=F[i]=2ni(ni)

然后剩下的请各位神犇随便推了QAQ
**

.. 0 1 2 3 4 5 0 20 21 22 23 24 25 1 20 221 322 423 525 2 20 321 622 1021 3 20 421 1022 4 20 521

**

Code

**
代码刚开始WA了……蒟蒻不明所以……so……
ORZ【点这里】

#include <bits/stdc++.h>using  namespace std;const int maxn=2e7+10;long long F,n,mod,ans,cnt,x,y;int inv[maxn];inline long long Pow(long long a,int k){    if(!k)return 1;    long long z=Pow(a*a%mod,k>>1);    if(k&1)return z*a%mod;    return z;}int main(){    cin>>n>>mod;    inv[1]=1;for(int i=2;i<=min(2*n,mod-1);i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;    ans=F=Pow(2,n);    for(int i=1;i<=n;i++)    {        int tmp=n-i+1;        while(tmp%mod==0)tmp/=mod,cnt++;        F=1ll*F*tmp%mod;        tmp=2*i;        while(tmp%mod==0)tmp/=mod,cnt--;        F=1ll*F*inv[tmp%mod]%mod;        ans^=cnt?0:F;    }    cout<<ans;    return 0;}


呵呵哒~

0 0
原创粉丝点击