首页 > 其他分享 >SP1825 FTOUR2 - Free tour II 题解

SP1825 FTOUR2 - Free tour II 题解

时间:2024-09-23 21:27:58浏览次数:6  
标签:siz cnt center weight FTOUR2 题解 Free int max

题目传送门

前置知识

点分治 | 树状数组

解法

维护点对信息,考虑点分治。

本题比 luogu P4149 [IOI2011] Race 多了个前缀查询 \(\max\)。套个支持单点修改、区间查询 \(\max\) 的数据结构即可。

直接线段树维护区间 \(\max\) 貌似会 TLE,换成树状数组维护前缀 \(\max\) 即可。

  • 注意数组偏移问题。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
struct node
{
	int nxt,to,w;
}e[400010];
int head[400010],col[400010],ask,ans=0,cnt=0;
void add(int u,int v,int w)
{
	cnt++;
	e[cnt].nxt=head[u];
	e[cnt].to=v;
	e[cnt].w=w;
	head[u]=cnt;
}
struct BIT
{	
	int c[400010];
	int lowbit(int x)
	{
		return (x&(-x));
	}
	void init()
	{
		memset(c,-0x3f,sizeof(c));
	}
	void add(int n,int x,int val)
	{
		for(int i=x;i<=n;i+=lowbit(i))
		{
			c[i]=max(c[i],val);
		}
	}
	int getsum(int x)
	{
		int ans=-0x3f3f3f3f;
		for(int i=x;i>=1;i-=lowbit(i))
		{
			ans=max(ans,c[i]);
		}
		return ans;
	}
	void clear(int n,int x)
	{
		for(int i=x;i<=n;i+=lowbit(i))
		{
			c[i]=-0x3f3f3f3f;
		}
	}
}T;
struct Divide_On_Tree
{
	int siz[400010],weight[400010],vis[400010],dis[400010],sum[400010],tmp[400010],d[400010],center=0;
	queue<int>q;
	void init(int n)
	{
		T.init();
		center=0;
		get_center(1,0,n);
		get_siz(center,0);
		divide(center);
	}
	void get_center(int x,int fa,int n)
	{
		siz[x]=1;
		weight[x]=0;
		for(int i=head[x];i!=0;i=e[i].nxt)
		{
			if(e[i].to!=fa&&vis[e[i].to]==0)
			{
				get_center(e[i].to,x,n);
				siz[x]+=siz[e[i].to];
				weight[x]=max(weight[x],siz[e[i].to]);
			}
		}
		weight[x]=max(weight[x],n-siz[x]);
		if(weight[x]<=n/2)
		{
			center=x;
		}
	}
	void get_siz(int x,int fa)
	{
		siz[x]=1;
		for(int i=head[x];i!=0;i=e[i].nxt)
		{
			if(e[i].to!=fa&&vis[e[i].to]==0)
			{
				get_siz(e[i].to,x);
				siz[x]+=siz[e[i].to];
			}
		}
	}
	void get_dis(int x,int fa,int rt)
	{
		if(sum[x]+col[rt]<=ask)
		{
			tmp[0]++;
			tmp[tmp[0]]=sum[x];
			d[tmp[0]]=dis[x];
			for(int i=head[x];i!=0;i=e[i].nxt)
			{
				if(e[i].to!=fa&&vis[e[i].to]==0)
				{
					dis[e[i].to]=dis[x]+e[i].w;
					sum[e[i].to]=sum[x]+col[e[i].to];
					get_dis(e[i].to,x,rt);
				}
			}
		}
	}
	void divide(int x)
	{
		T.add(ask+2,0+1,0);
		q.push(0);
		vis[x]=1;
		for(int i=head[x];i!=0;i=e[i].nxt)
		{
			if(vis[e[i].to]==0)
			{
				tmp[0]=0;
				dis[e[i].to]=e[i].w;
				sum[e[i].to]=col[e[i].to];
				get_dis(e[i].to,x,x);
				for(int j=1;j<=tmp[0];j++)
				{
					ans=max(ans,T.getsum(ask-tmp[j]+1)+d[j]);
				}	
				for(int j=1;j<=tmp[0];j++)
				{
					T.add(ask+2,tmp[j]+col[x]+1,d[j]);
					q.push(tmp[j]);
				}
			}
		}
		while(q.empty()==0)
		{
			T.clear(ask+2,q.front()+col[x]+1);
			q.pop();
		}
		for(int i=head[x];i!=0;i=e[i].nxt)
		{
			if(vis[e[i].to]==0)
			{
				center=0;
				get_center(e[i].to,x,siz[e[i].to]);
				get_siz(center,0);
				divide(center);
			}
		}
	}
}D;
int main()
{
	int n,m,u,v,w,i;
	cin>>n>>ask>>m;
	for(i=1;i<=m;i++)
	{
		cin>>u;
		col[u]=1;
	}
	for(i=1;i<=n-1;i++)
	{
		cin>>u>>v>>w;
		add(u,v,w);
		add(v,u,w);
	}
	D.init(n);
	cout<<ans<<endl;
	return 0;
}

标签:siz,cnt,center,weight,FTOUR2,题解,Free,int,max
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18427897

相关文章

  • LGP3183 题解
    原题链接:P3183[HAOI2016]食物链。难度:Easy。根据定义,食物链是一个DAG,所以可以进行拓扑排序。食物链也就转化成了:图中从一个入度为\(0\)的点到一个出度为\(0\)的点的路径。那么只需要拓扑排序求出所有起点到每个点的路径条数,然后累加出度为\(0\)的点的值即可。需要注......
  • LGP1901 题解
    原题链接:P1901发射站难度:Easy。注意到"最近的且比它高",容易想到用单调栈维护每个能量发射站左右第一个比它高的,最后统计答案即可。具体的令f[i][0/1]表示能量发射站\(i\)右边/左边第一个\(h_x>h_i\)的位置\(x\)。用单调栈从左向右扫一遍,得到f[i][0]。用单调栈从右......
  • [题解] ICPC网络预选赛 2024 第二场 E Escape (含题目翻译)
    [题解]ICPC网络预选赛2024第二场EEscape(含题目翻译)tag:图论、BFS、最短路题干为原文DeepL翻译题目描述Sneaker在一个巨大的迷宫中醒来,现在他想逃离这个迷宫。通过迷宫中每个房间的地图,Sneaker了解了迷宫的结构。迷宫由......
  • 【题解】Solution Set - NOIP2024集训Day36 dp 优化 + 状态设计
    【题解】SolutionSet-NOIP2024集训Day36dp优化+状态设计https://www.becoder.com.cn/contest/5550最后一题较难。「NOIP2023」天天爱打卡考虑dp。\(f_{i,j}\):前\(i\)天,到第\(i\)天为止连续打卡\(j\)天。有转移:\[f_{i,0}=\max(f_{i,j})\\f_{i,j}=\max(f_{i......
  • Codeforces Round 972(Div.2)题解
    CodeforcesRound972(Div.2)题解A.SimplePalindrome贪心贪心,尽可能元素数量平均,并且相同字母放在一起。#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.end()#defineendl'\n'#de......
  • Codeforces Round 973 (Div.2) A-E题解
    CodeforcesRound973(Div.2)A-E题解比赛传送门A.Zhan'sBlender数学显然答案为\(\lceil\frac{n}{min(x,y)}\rceil\)。#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.en......
  • 题解:AT_abc372_e [ABC372E] K-th Largest Connected Components
    题意给出\(q\)个操作。将\(u\)和\(v\)连边。问\(u\)所在的连通块中编号第\(k\)大的点。思路连通块很容易想到并查集,求第\(k\)大可以用平衡树(虽然赛时没看到\(k\le10\)),合并时将信息从将小的连通块合并到大的连通块,这样可以减少时间复杂度。什么?你不会写平衡......
  • 题解:AT_arc184_a [ARC184A] Appraiser
    题意\(1000\)个硬币中有\(10\)个假币,你每次可以询问两个位置的硬币类型是否相同,你需要用不超过\(950\)次询问找出所有假币的位置。思路将前\(990\)个硬币每\(11\)个分一组,共\(90\)组,余\(10\)个单独分一组。询问每组第\(1\)个硬币和这组后面硬币的关系。因为只......
  • CF1270H Number of Components 题解
    Description给一个长度为\(n\)的数组\(a\),\(a\)中的元素两两不同。对于每个数对\((i,j)(i<j)\),若\(a_i<a_j\),则让\(i\)向\(j\)连一条边。求图中连通块个数。支持\(q\)次修改数组某个位置的值,每次修改后输出图中连通块个数。\(n,q\le5\times10^5,1\lea_i\le10^......
  • 2024ICPC网络赛第二场题解(部分)
    前言这场相对作用大一点,最后顶着队友的怀疑压力乱搞出了C,但是后面看题解发现似乎是数据弱了跑过去,其实复杂度是队友分析的那样,是不正确的,但是毕竟是打名额的比赛,过了就是过了,这里分享一下C题的乱搞做法,以及其他题的我们队赛时代码。下面的顺序按过题顺序(也差不多是难度递增顺序)......