T2
第一二个测试点直接 (O(nm)) 暴力就可以了吧。但是需要注意 1e4 * 1e4 要卡常, T 掉的大概吧把 max 函数手写一下,写成 #define max(a,b) (a>b?a:b)就可以了
for(int i=1;i<=q;++i){
x=read();ans=0;
for(int j=1;j<=n;++j)
ans=max(ans,k[j].a*x*x+k[j].b*x);
printf("%lld
",ans);
}
}
T3
第一个点设f[i][j][k][l][r]分别表示5个点都剩下多少,记忆化搜索。
第二个点的 (a_i <= 1) 就是 (frac {cnt_1 + 1} {2}),当 (n == 2) 时,最后必然是 (a_1) 选完, (a_2) 可能选完,可能不选完,分情况讨论,如果不选完,设 (a_2) 选 (i) 个,首先确定最后一个必然是选择 (a_1),前面是排列组合,最后结果是 (sumlimits_{i=0}^{a_1-1} C^{i}_{a_1-1+i} imes(a_1 + i) imes(frac{1}{2})^{a_1+i}) ,如果选完的话,设选完所有 (a_2) 后还剩 (i) 个 (a_1) ,那么最后结果就是 (sumlimits_{i=0}^{a_2-1} C^{a_1-i}_{a_1i+a_2-i-1} imes(a_2+a_1) imes(frac{1}{2})^{a_1+a_2-i})
T4
(a_i < 2) 设 (g_i) 表示i以上偶数位有几个是1,直接递推就能求出,然后计算用 (g_u + g_v -2 imes g_{lca}) ,(f_i) 记录 (a_i) 之和,然后直接计算
其他大概直接暴力就可以了,我的写法就是先跑树剖 LCA,然后在从 u 和 v 依次向上跑到LCA处,然后 u 的话 xor 的值从 0 向上加, v 的话从 (dep_u+dep_V-2*dep_{LCA}) 开始减到LCA处,最后就是答案,效率是 (O(n^2))
#define v edge[i].to
long long search(register const int u,register const int zd,register const int cd){
if(u==zd)return 0;
register long long ans=a[u]|cd;
for(register int i=head[u];i;i=edge[i].next)
if(dep[v]==dep[u]-1)ans+=search(v,zd,cd+1);
return ans;
}
long long search2(register const int u,register const int zd,register const int cd){
if(u==zd)return 0;
register long long ans=a[u]|cd;
for(register int i=head[u];i;i=edge[i].next)
if(dep[v]==dep[u]-1)ans+=search2(v,zd,cd-1);
return ans;
}
#undef v
inline long long LCA(register int x,register int y){
register int lca;
register const int u=x,w=y;
register long long ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]])swap(x,y);
y=f[top[y]];
}
lca=dep[x]<dep[y]?x:y;
ans=a[lca]|(dep[u]-dep[lca]);
ans+=search(u,lca,0);
ans+=search2(w,lca,dep[u]+dep[w]-2*dep[lca]);
return ans;
}