20211005下午
T
2
T2
T2倒在了找勾股数的第一步。
T1 | T2 | T3 | |
---|---|---|---|
预测 | 100 | 0 | 100 |
一测 | 100 | 0 | 100 |
T1:
若当前数字位数为
m
m
m,则有
f
n
=
f
n
−
1
×
1
0
m
+
n
f_n=f_{n-1}\times 10^m+n
fn=fn−1×10m+n,显然可以用矩阵转移。
因为位数会变化,所以分开转移就行。
T2:
首先,你需要知道,勾股数存在一般表示形式为
(
x
2
−
y
2
)
+
2
x
y
=
(
x
2
+
y
2
)
(x^2-y^2)+2xy=(x^2+y^2)
(x2−y2)+2xy=(x2+y2),而且根据勾股数的稀疏性推断出可以对互质勾股数对进行建图,题目便转化为一个图上
N
P
NP
NP问题。
图上
N
P
NP
NP问题?那跑个啥啊?复杂度直接飞起。
然而这事实上是个仙人掌,非树边相当少,所以对这些非树边进行容斥后树形
d
p
dp
dp即可。
void Dfs(int x,int fa) //找非树边
{
vis[x]=true;
for(int u=first[x];u;u=nxt[u])
{
if(to[u]==fa) continue;
if(vis[to[u]]) e[++num].u=x,e[num].v=to[u],un_tree[u]=un_tree[u^1]=true;
else Dfs(to[u],x);
}
return;
}
void dp(int x,int fa) //树形dp
{
f[x][0]=1;f[x][1]=pow2[cnt[x]]-1;
if(lim[x]==tmp) f[x][0]=0;
for(int u=first[x];u;u=nxt[u])
{
if(to[u]==fa||un_tree[u]) continue;
dp(to[u],x);
f[x][0]=f[x][0]*(f[to[u]][0]+f[to[u]][1])%mod;
f[x][1]=f[x][1]*f[to[u]][0]%mod;
}
return;
}
int get1(int x)
{
int res=0;
for(;x;x>>=1) res+=x&1;
return res;
}
ll solve(int x)
{
num=0;Dfs(x,0);
ll res=0;
for(int i=0,l=1<<num;i<l;i++)
{
++tmp;
for(int j=0;j<num;j++) if(i>>j&1) lim[e[j+1].u]=lim[e[j+1].v]=tmp;
dp(x,0);
res=(res+((f[x][0]+f[x][1])*(get1(i)&1?mod-1:1)%mod))%mod;
}
return res;
}
T3:
期望
d
p
dp
dp(其实是概率),因为无法解异或方程,所以对每一位拆分。
f
u
,
i
f_{u,i}
fu,i表示
u
u
u节点到
n
n
n点路径的二进制第
i
i
i位为
1
1
1的概率,所以有
f
u
,
i
=
∑
f
v
,
i
×
[
(
w
>
>
i
)
&
1
=
0
]
+
(
1
−
f
v
,
i
)
×
[
(
w
>
>
i
)
&
1
=
1
]
f_{u,i}=\sum{f_{v,i}\times[(w>>i)\And 1=0]+(1-f_{v,i})\times[(w>>i)\And1=1]}
fu,i=∑fv,i×[(w>>i)&1=0]+(1−fv,i)×[(w>>i)&1=1]
因为有自环且为无向图,所以需要高斯消元。
总结:玄学题真是。