首页 > 其他分享 >CF974 Review

CF974 Review

时间:2024-09-24 21:36:07浏览次数:1  
标签:tote int Review st CF974 while void dp

CF974 Review

(以后比较简单的题就不写了)

A B C

skip

D

个人写了 \(O(n\log n)\) 的类模拟算法,能过,但不能做到 $O(n) $ 。

考虑什么时候一段 \([st,st+d-1]\) 的时间会和某一段区间有重合,也就是我自己写的算法的核心思想其实。

那就是 $st+d-1\ge l_i \quad st\le r_i $ ,变形一下就可以得到 \(l_i-d+1\le st\le r_i\) ,也就是会对所有满足开头 \(st\) 在上述范围内的答案产生 \(+1\) 的贡献,那么直接进行差分数组区间加就可以了。

E

仍然是普通的最短路,但是到了某些节点之后(有马),就可以使得之后的前进过程都只消耗 \(w/2\) 的代价,并且是两个人同时出发,最后在一点汇合(可以停下等待)。

后者非常好解决,我们只需要跑两次最短路,然后枚举中间汇合的点就好了。

那么如何处理前者?就要用到分层最短路。

对于任何一个有马的节点,我们都向更高一层建一条边,而更高一层的所有边权都是底层对应的一半。最后的最短路就是两张图取一个 min 就行。

#include<bits/stdc++.h>
#define int long long 
using namespace std;
template<typename T>inline void re(T &x)
{
	x=0;int f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	x*=f;
}
template<typename T>inline void wr(T x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)wr(x/10);
	putchar(x%10^48);
}
int n,m,h;
struct Edge
{
	int u,v,w,nex;
}e[2000010];
int tote,head[400010],vis[400010];
inline void add(int u,int v,int w)
{
	e[++tote].u=u,e[tote].v=v,e[tote].w=w;
	e[tote].nex=head[u],head[u]=tote;
}
struct Node
{
	int x,dis;
};
bool operator <(Node a,Node b)
{
	return a.dis>b.dis;
}
const int inf=1e15+1;
int dis1[400010],disn[400010];
inline void dj()
{
	for(register int i=1;i<=2*n;++i)dis1[i]=inf,vis[i]=0;
	dis1[1]=0;
	priority_queue<Node> q;
	q.push(Node{1,0});
	while(q.size())
	{
		int x=q.top().x;q.pop();
		if(vis[x])continue;
		for(int i=head[x];i;i=e[i].nex)
		{
			int v=e[i].v,w=e[i].w;
			if(dis1[x]+w<dis1[v])
			{
				dis1[v]=dis1[x]+w;
				q.push(Node{v,dis1[v]});
			}
		}
		vis[x]=1;
	}
	
	for(register int i=1;i<=2*n;++i)disn[i]=inf,vis[i]=0;
	disn[n]=0;
	priority_queue<Node> q1;
	q1.push(Node{n,0});
	while(q1.size())
	{
		int x=q1.top().x;q1.pop();
		if(vis[x])continue;
		for(int i=head[x];i;i=e[i].nex)
		{
			int v=e[i].v,w=e[i].w;
			if(disn[x]+w<disn[v])
			{
				disn[v]=disn[x]+w;
				q1.push(Node{v,disn[v]});
			}
		}
		vis[x]=1;
	}
	
}	
inline void pre()
{
	tote=0;
	memset(head,0,sizeof(head));
	re(n),re(m),re(h);
	int tmp;
	for(register int i=1;i<=h;++i)
	{
		re(tmp);
		add(tmp,tmp+n,0);
	}
	for(register int i=1;i<=m;++i)
	{
		int u,v,w;
		re(u),re(v),re(w);
		add(u,v,w),add(v,u,w);
		add(u+n,v+n,w/2),add(v+n,u+n,w/2);
	}
	dj();
//	puts("display:");
//	for(register int i=1;i<=n;++i)printf("%lld ",dis1[i]);
//	printf("\n");
//	for(register int i=1;i<=n;++i)printf("%lld ",disn[i]);
//	printf("\n");
}
inline void solve()
{
	int ans=1e15+2;
	for(register int i=1;i<=n;++i)
	{
		if(dis1[i]==inf||disn[i]==inf)continue;
		ans=min(ans,max(min(dis1[i],dis1[i+n]),min(disn[i],disn[i+n])));
	}
	if(ans==1e15+2)puts("-1");
	else wr(ans),putchar('\n');
}
signed main()
{
	int T;
	cin>>T;
	while(T--)
	{
		pre();
		solve();
	}
	return 0;
}

F

一道很基础的树形dp,当时前四道题交了六发罚时心态爆炸没看后面了。

实际上我也不知道我能不能做出来,虽然这个树形dp确实贴脸上了。

定义 \(dp[x][0/1]\) 为当前点 \(x\) 选/不选,能得到的以 \(x\) 为根的子树的最大价值。

由于考虑的是一个树形结构,所以如果要选择当前节点,我们只用考虑它向下的影响,因为之后我们会在他的计算他的父亲时考虑它向上的影响。

当然还需要注意的就是我们只会统计维修过的节点,因此如果一个节点的状态是没有维修,也就是 \(dp[x][0]\) ,那么附近的节点是不会对它产生 \(-c\) 的影响的,所以只有当一条边连接的两个点状态都是 \(1\) 的时候才会考虑 \(c\) ,而且是 \(-2*c\) 。转移过程如下(直接贴代码了):

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int T,n,c;
const int N=2e5+10;
vector<int> e[N];
int a[N],dp[N][2];
inline void dfs(int x,int fa)
{
	int s1=0,s0=0;
	for(auto v:e[x])
	{
		if(v==fa)continue;
		dfs(v,x);
		s1+=max(dp[v][1]-2*c,dp[v][0]);
		s0+=max(dp[v][1],dp[v][0]);
	}
	dp[x][1]=max(dp[x][1],s1+a[x]);
	dp[x][0]=max(dp[x][0],s0);
}
inline void pre()
{
	cin>>n>>c;
	for(register int i=1;i<=n;++i)cin>>a[i],dp[i][0]=dp[i][1]=0,e[i].clear();
	for(register int i=1;i<=n-1;++i)
	{
		int u,v;
		cin>>u>>v;
		e[u].push_back(v),e[v].push_back(u);
	}
}
signed main()
{
	cin>>T;
	while(T--)
	{
		pre();
		dfs(1,0);
		cout<<max(dp[1][1],dp[1][0])<<endl;
	}
	return 0;
}

F G

还没改(估计鸽了

标签:tote,int,Review,st,CF974,while,void,dp
From: https://www.cnblogs.com/Hanggoash/p/18430089

相关文章

  • ABC372 Review
    ABC372ReviewA语言基础题B类似于二进制拆分,就像跳LCA的时候一样,尽可能多地选大的即可。C一个位置的字母被改变仅仅会对相邻两个位置之类的答案产生影响,暴力统计即可。D对于每一个\(i\)去暴力地统计\(j\)显然是不可行的,所以可以转而想一想每个\(j\)会对答案产生多......
  • AI应用的代码审查CodeReview
    AI应用的代码审查CodeReview提示词AsaDeveloper,IwanttoaskyoutoperformaGitHubMergeRequestreview.https://github.com/megadotnet/Springboot-chatapp/commit/3f7c3e2cb919c3d971d10c301da2357d635d7302Considerpreviouscommentsnotedbelowandavoidrepeati......
  • ABC371 Review
    ABC371ReviewA分类讨论题,过B模拟题,过C题意给出一张原始图\(G\),和一张待修改图\(H\),每次对\(H\)进行一次操作可以花费相应的代价删除已经存在的一条边或者是添加未存在的边。问使得两张图同构的最小代价\(W\)是多少。思路以为是什么高级的算法,但是又放在了C......
  • VS2022 17.12.0 Preview2版本对Copilot的功能增强
    前提条件,使用最新版的17.12.0Preview2,并且有有效的CopilotAI订阅,那么可以体验这些新鲜好用的功能增强了CopilotAI对IEnumerableVisualizer的可编辑表达式功能我们可以通过AI实现一些复杂的条件筛查,并且可以即时验证结果是否符合预期,对于开发和调试提供了极大的便利性......
  • ABC370 Review
    ABC370ReviewA模拟题,过B模拟题,过C很明显的贪心思路是把需要更改的字母分为两类:改大和改小。首先我们要明确的是要让输出的串尽量拥有小的字典序,且字典序比较的第一关键字是位置,第二是长度所以对于改小的部分,改的位置越靠前我们就放在越前面操作;对于改大的部分,改的位置......
  • 使用 nuxi preview 命令预览 Nuxt 应用
    title:使用nuxipreview命令预览Nuxt应用date:2024/9/8updated:2024/9/8author:cmdragonexcerpt:摘要:本文介绍了如何使用nuxipreview命令预览Nuxt.js应用,包括安装和准备环境、启动预览服务器的步骤,以及如何指定根目录和使用自定义.env文件等高级用法。通过nuxip......
  • J.U.C Review - ThreadLocal原理源码分析
    文章目录一致性问题一致性问题简介解决一致性问题的常见方法ThreadLocal什么是ThreadLocalThreadLocal的线程模型ThreadLocal的工作原理使用场景ThreadLocal的基本API1.构造函数`ThreadLocal()`2.初始化方法`initialValue()`3.访问器`get()`和`set()`4.......
  • J.U.C Review - 计划任务ScheduledThreadPoolExecutor源码分析
    文章目录TimeVSScheduledThreadPoolExecutor小DemoScheduledThreadPoolExecutor类结构ScheduledThreadPoolExecutor主要方法介绍scheduleDelayed接口ScheduledFuture接口RunnableScheduledFuture接口ScheduledFutureTask类scheduleAtFixedRatescheduleWithFixedDelayd......
  • 【零基础 快速学Java】韩顺平 零基础30天学会Java--- 常用类(2024JavaReview)
    包装类包装类的分类(针对八种基本数据类型相应的引用类型—包装类)(有了类的特点,就可以调用类中的方法)(实现了接口Serializable【String可以串行化:可以在网络传输】)(实现了接口Comparable[String对象可以比较大小])包装类和基本数据的转换(jdk5前的手动装箱和拆箱方式,jdk5以后(含j......
  • 【零基础 快速学Java】韩顺平 零基础30天学会Java--- 面向对象编程(中级部分)(2024Jav
    IDEA常用快捷键添加注释和取消注释ctrl+/【第一次是添加注释,第二次是取消注释】导入该行需要的类先配置autoimport,然后使用alt+enter即可快速格式化代码ctrl+alt+L生成构造器等alt+insert[提高开发效率]查看一个类的层级关系ctrl+H[学习继承后,非常有用]......