//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

10.20模拟赛

T1

传送门
本题是我有史以来第一次在比赛中打出线段树,然而他MLE了。。。
正解其实很简单,就是用一个时间戳数组维护一个点上一次修改的值有没有修改,然后需要算当前点的值的时候在修改就可以了。
code

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
//#define int long long
#define N 10000100
#define rs x<<1|1
#define ls x<<1
using namespace std;
int a[N],p,t[N],n,q,res,now;//now是上一次修改的值,a存放每一个点的值,t存放上一次修改成了什么值 
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){f=ch!='-';ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return f?x:-x;}
signed main()
{
	n=read();q=read();
	while(q--)
	{
		int op,x,y;
		op=read();
		if(op==1)
		{
			x=read();
			y=read();
			if(t[x]==now)res=res+(y-a[x]);//如果当前点的值是已经修改过的就直接修改 
			else res=res+y-p;//否则就用修改了的值计算 
			a[x]=y-p;//当前点的值更新一下 
			t[x]=now;//更新当前点上一次更新的值 
			printf("%lld\n",res);//输出 
		}
		else if(op==2)
		{
			x=read();
			y=read();
			res+=y;//无论如何res都要加y 
			if(t[x]==now)a[x]+=y;//等于就直接加 
			else t[x]=now,a[x]=p+y;//否则就修改 
			printf("%lld\n",res);//输出 
		}
		else if(op==3)
		{
			y=read();
			now++;//当前点的修改次数加一
			p=y;//存下修改的值 
			res=p*n;//更新res
			printf("%lld\n",res);//输出 
		}
	}
	return 0;//好习惯 
}

T2

题面
这道题一开始我看了之后就觉得不可做,所以我就直接放了。
正解需要拓扑排序,首先入度为零的话那就一定是个起点,然后根据这些起点跑一个SPFA来求最长路,遍历一下输出答案就好了。。
code

#include<bits/stdc++.h>
#define int long long
using namespace std;
struct sb{int v,next,w;}e[1000100];
int head[1000100],cnt,ru[100010];
inline void add(int u,int v,int w)//存边函数 
{
	e[++cnt].v=v;
	e[cnt].w=w;
	e[cnt].next=head[u];
	head[u]=cnt;
	return ;
}
int n,m,f[100010];//f是当前起点到终点的最长路 
queue<int>q;//队列 
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
		ru[v]++;//入度 
	}
	for(int i=1;i<=n;i++)
	  if(ru[i]==0)
	    q.push(i);//入读为零是起点入列 
	while(!q.empty())//不空 
	{
		int x=q.front();//取出下标 
		q.pop();
		for(int i=head[x];i;i=e[i].next)//遍历相连的边 
		{
		  if(f[e[i].v]<f[x]+e[i].w)//如果当前点的距离小于 
		    f[e[i].v]=f[x]+e[i].w;//替换 
		  ru[e[i].v]--;//入度减一 
		  if(ru[e[i].v]==0)//入度为零了就入列 
		    q.push(e[i].v);
		}
	}
	int ans=0;//答案 
	for(int i=1;i<=n;i++)
	  ans=max(ans,f[i]);//遍历求最大值 
	cout<<ans<<endl;//输出答案 
	return 0;//好习惯 
}

T3

题面

posted @ 2022-10-20 22:26  北烛青澜  阅读(12)  评论(0编辑  收藏  举报