3 条题解
-
2
这个题目是一个数学题,打表可以发现答案是……好了,言归正传。
下文设 为字符串 在 时的值,字符串间的 为
C++/STL/string
中的字符串拼接。设 和 中与 匹配次数较少的字符串为 (另一个为 ),则 ,且 和 的最后一位一定不同。
证明:
首先, 时显然成立,即样例 。
接下来,从 推到 :
下面的性质很显然,证明不给了。
;
;
( 是 改变最后一位,即 变成 , 变成 后的字符串)。
可以发现,此时 $\operatorname{mc}(A_{N+1},C_{N+1})=\operatorname{mc}(A_{N},C_{N})+\operatorname{mc}(B_{N},C_{N})+\operatorname{mc}(A_{N},D_{N})$,$\operatorname{mc}(B_{N+1},C_{N+1})=\operatorname{mc}(B_{N},C_{N})+\operatorname{mc}(A_{N},C_{N})+\operatorname{mc}(B_{N},D_{N})$。
若 ,且 和 的最后一位不同,则 。
而由于当 与 「合在一起」(每个位置两个字符)时,每位各出现了一个 和一个 (必有一个和 对应位置匹配),因此 $\operatorname{mc}(G_{N},D_{N})+\operatorname{mc}(H_{N},D_{N})=3^N$。
也就是说,。
它们之间差 ,因此 与 之间也差 (其余的抵消了)。
同理,$\operatorname{mc}(G_{N+1},C_{N+1})+\operatorname{mc}(H_{N+1},C_{N+1})=3^{N+1}$。
因此,$\operatorname{mc}(G_{N+1},C_{N+1})=\dfrac{3^{N+1}-1}{2}$(列方程组可得)。
此外,由于 $\operatorname{mc}(H_{N},D_{N})<\operatorname{mc}(G_{N},D_{N})$,因此 的展开式(指「可以发现」那一句中的公式)中的最后一项是 。
而由于 与 , 与 , 与 的最后一位都不同,因此 与 的最后一位也不同,即 与 的最后一位也不同。
根据数学归纳法,得证。
也就是说,答案就是 !
std:
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x * f; } const ll mod = 1000000007; ll T; inline ll power(ll a, ll b) { ll ans = 1; while(b) { if(b & 1) ans = (ans * a) % mod; a = (a * a) % mod; b >>= 1; } return ans; } signed main() { T = read(); while(T--) { ll x = read(); x %= mod - 1; ll a = power(3, x) - 1; printf("%lld\n", ((a & 1) ? a + mod : a) / 2); } return 0; }
-
1
打表大法好啊:
#include<bits/stdc++.h> using namespace std; const long long mod=1e9+7; int power(long long a,long long b){ long long ans=1; while(b){ if(b&1){ ans=ans*a%mod; } a=a*a%mod; b>>=1; } return ans; } int main(){ int T; cin>>T; while (T--) { long long n; cin>>n; long long a=power(3,n)-1; cout<<((a & 1) ? a + mod : a) / 2<<endl; } }
- 1
信息
- ID
- 6
- 时间
- 500ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- (无)
- 递交数
- 10
- 已通过
- 6
- 上传者