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

posted @ 2019-10-18 00:00  Miemeng_麦蒙  阅读(98)  评论(0编辑  收藏  举报

小麦在雨中,蒙蒙的雾气

麦蒙不想有人骚扰他,如果有必要 联系 QQ:1755601414

如果你嫌广告大,那就喷我吧,不是博客园的锅。