1. 1 Refrain Anan Ryoko
  2. 2 镇命歌 -しずめうた- 瀧沢一留
  3. 3 Pure SCHAT10(影)
  4. 4 Lemon Soda NGC 3.14/Tenkitsune
  5. 5 summer vibe Cyan Lpegd
  6. 6 DJ Okawari - Flower Dance(钢琴原版) Oturans
  7. 7 花降らし n-buna/初音ミク
  8. 8 Lemon 米津玄師
  9. 9 明けない夜、醒めない夢 Yunomi
  10. 10 ニゲラの花束 鎖那
  11. 11 ひだまりの郷 八乙女葦菜
  12. 12 Pneumatic Tokyo EnV
  13. 13 摘星座的女孩 Rainbowets
Refrain - Anan Ryoko
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

洛谷 5947 [POI2003]Trinomial 题解

题意简述

TT组数据。给定n,mn,m,求(x2+x+1)n(x2+x+1)n中,xmxm项的系数是多少。答案对33取膜。
(这个膜数很神奇!注意!突破点就在这!)

T<=1e4T<=1e4n<=1e15n<=1e15m<=2nm<=2n

思路框架

答案是Cm2n×(m%2+1)Cm2n×(m%2+1),对33取膜(写个LucasLucas即可)

具体思路

首先,我们分括号讨论。因为是(x2+x+1)n(x2+x+1)n,所以有nn个括号,并且每个括号可以出x2,x,1x2,x,1。然后我们要求,有多少种方案使得每个括号中出的数积为xmxm

我们开始打草稿:我们把nn个括号从11nn顺序编号,每个括号上面有两个复选框。打了几个勾,就是代表出xx的多少次方。具体来说就是:
一个都没打勾,代表出x0x0x0x0就是11);其中一个打了勾,代表出xx;两个都打了勾,代表出x2x2

如图所示是n=4n=4的情况:
blog1.jpg

我们这样勾选:
blog2.jpg

那就相当于:
第一个括号出xx
第二个括号出x2x2
第三个括号出xx
第四个括号出xx
那它就会给x5x5那一项贡献一种情况。

那么我们现在考虑xmxm项的系数,换句话说就是有多少种方法凑出xmxm

显然,上面的复选框中,我们每打一个勾,乘出来就多一个xx。(上面打了55个勾,乘起来就是x5x5)然后一共有2n2n个复选框,所以答案就是Cm2nCm2n

这就完了?不!这样考虑有重复的!

假如第ii个括号出的是xx,那就相当于在ii上面两个复选框中,其中一个要打勾。而我们只在意数量,具体打勾打上面那个框还是下面的那个,是一样的。那就会把一个答案算两遍,所以要除以22

假设我们有kk个括号出的是xx,那么我们的答案就要除以一个2k2k

首先,kkmm肯定是同奇偶的。

稍微证一下(会证跳过): 有kk个括号出xx,那剩下xmkxmk都是由出11x2x2组成的。mkmk由若干个0022相加而成,所以mkmk是偶数。所以mmkk同奇偶。

然后,在模三意义下,2的逆元就是其本身!所以,除以一个2k2k,就相当于乘以一个2k2k

还没完,我们继续化。我们发现,22的幂除以33的余数是:2,1,2,1,2,12,1,2,1,2,1。具体点说,2k%3=(k%2)+12k%3=(k%2)+1。而kkmm又同奇偶,所以,所有的k%2+1k%2+1都等于m%2+1m%2+1

综上,我们的答案就是Cm2n×(m%2+1)Cm2n×(m%2+1)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define int long long
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
#define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
#define p_b push_back
#define sz(a) ((int)a.size())
#define iter(a,p) (a.begin()+p)
void R1(int &x)
{
x=0;char c=getchar();int f=1;
while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=(f==1)?x:-x;
}
void Rd(int cnt,...)
{
va_list args;
va_start(args,cnt);
F(i,1,cnt)
{
int* x=va_arg(args,int*);R1(*x);
}
va_end(args);
}

int n,m;
void Input()
{
Rd(2,&n,&m);
}

int c[4][4];
int C(int n,int m) //卢卡斯定理求C(n,m)%3
{
if (n==0 and m==0) return 1;
return C(n/3,m/3)*c[n%3][m%3]%3;
}
void Soviet()
{
c[0][0]=1;
c[1][1]=c[1][0]=1;
c[2][0]=c[2][2]=1;c[2][1]=2; //预处理<3的组合数
printf("%lld\n",C(2*n,m)*(m%2+1)%3); //用上面的式子
}

#define Flan void
Flan IsMyWife()
{
int t;R1(t);
F(i,1,t)
{
Input();
Soviet();
}
}
#undef int //long long
}
int main(){
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}
w