联赛模拟测试32

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\n",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\),前面是排列组合,最后结果是 \(\sum\limits_{i=0}^{a_1-1} C^{i}_{a_1-1+i}\times(a_1 + i)\times(\frac{1}{2})^{a_1+i}\) ,如果选完的话,设选完所有 \(a_2\) 后还剩 \(i\)\(a_1\) ,那么最后结果就是 \(\sum\limits_{i=0}^{a_2-1} C^{a_1-i}_{a_1i+a_2-i-1}\times(a_2+a_1)\times(\frac{1}{2})^{a_1+a_2-i}\)

T4

\(a_i < 2\)\(g_i\) 表示i以上偶数位有几个是1,直接递推就能求出,然后计算用 \(g_u + g_v -2 \times 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;
}
posted @ 2020-11-11 17:51  goote~  阅读(60)  评论(0编辑  收藏  举报
Live2D