19-10-18-Night-U
话说T3:
一句话题意……见过这个嘛……

于是:$\sum \limits_{i!=j} \binom{a_i+b_i+a_j+b_j}{a_i+a_j}$
------------前言结束----------------
------------正文开始----------------
正文加载中……
T1
倍增,又是倍增。
于是找到节点$i$的祖先链上第一个比它大的点,并以他为$fa_{i,0}$
这样跑跑倍增就可以了。
(虽然我是直接跳$fa$水果的)
这里是蒟蒻竞争场+的赢家的代码,仿佛是正解。
#include<bits/stdc++.h>
using namespace std;
#define maxn 101000
#define inf 2000000000
int n,que,w[maxn],u,v,c;
int head[maxn],js,deep[maxn],fa[maxn][25];
struct node{int ne,to;}tree[maxn*2];
void qxx(int fr,int tt)
{
tree[++js].ne=head[fr];
head[fr]=js;
tree[js].to=tt;
}
int find(int ro,int c)
{
if(w[ro]>c) return ro;
for(int j=20;j>=0;--j)
if(w[fa[ro][j]]<=c) ro=fa[ro][j];
return fa[ro][0];
}
void dfs(int ff,int ro)
{
for(int i=head[ro];i;i=tree[i].ne)
{
int son=tree[i].to;
if(son==ff) continue;
deep[son]=deep[ro]+1;
int ls=find(ro,w[son]); fa[son][0]=ls;
for(int j=1;j<=20;++j) fa[son][j]=fa[fa[son][j-1]][j-1];
dfs(ro,son);
}
}
int ask(int son,int ro)
{
int sum=0;
for(int j=20;j>=0;--j)
if(deep[fa[son][j]]>=deep[ro])
{
son=fa[son][j];
sum+=(1<<j);
}
return sum;
}
int main()
{
scanf("%d%d",&n,&que);
for(int i=1;i<=n;++i) scanf("%d",&w[i]);
for(int i=1;i<n;++i)
{
scanf("%d%d",&u,&v);
qxx(u,v); qxx(v,u);
}
deep[1]=1; w[0]=inf; dfs(0,1);
for(int o=1;o<=que;++o)
{
scanf("%d%d%d",&u,&v,&c);
int fir=find(u,c);
if(deep[fir]<deep[v]) {puts("0"); continue;}
else
{
int ans=1;
int ls=ask(fir,v);
//cout<<fir<<"->"<<v<<":"<<ls<<endl;
ans+=ls;
printf("%d\n",ans);
}
}
return 0;
}
T2
三元环计数,虽然没A但是可以口胡一下
首先因为走最短的环所以并不能走四元环,
因为在竞赛图里,
两点之间一定有边相连,所以一定可以将四元环拆成两个三元环来走。
T3
考场上丢出一个暴力,获得20分,后来说可以把柿子化成:

注释:
蒟蒻竞技场是比谁最后一个AC的竞技场,
由超级大蒟蒻Miemeng发起,
但是他非常不要×的自己拿了很多Rank1
Miemeng真的蒻

浙公网安备 33010602011771号