首页 > 其他分享 >CSP 模拟 52

CSP 模拟 52

时间:2024-10-21 14:59:08浏览次数:1  
标签:return int res 52 inline root CSP 模拟 dis

B 最短路

先建出最短路 DAG,保证最短路径唯一,所以建出来的 DAG 是一棵树。考虑一个点的答案可以由谁来更新,假设当前点为点 \(u\),它的 dfs 序控制范围是 \(l,r\)。首先,它可以由子树外除了父亲的节点来更新,形如 ans[u]=dis[v]+w,它也可以由子树内的节点更新,路径形如 1->zc->v->u,要求中转点 \(zc\) 必须在 \(u\) 的子树外,形式化的来说 \(ans_u=\min(dis_{zc}+w_{zc\to v})+w_{v\to u}[l\le dfn_{zc}\le r]\),然后问题就成了一个单点修改,区间查询最小值的问题,从下往上线段树合并即可,时间复杂度 \(\mathcal{O}(n\log n)\),常数比较小,比大部分正解要快。

#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pii std::pair<int,int>
#define eb emplace_back
typedef long long ll;
typedef unsigned long long ull;
std::mt19937 myrand(std::chrono::high_resolution_clock::now().time_since_epoch().count());
inline int RR(int n){return myrand()%n+1;}
inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;}
const int N=1e5+10,mod=998244353;
const int inf=1e18;
inline void Min(ll &x,ll y){if(x>y)x=y;}
inline void Max(int &x,int y){if(x<y)x=y;}
inline void W(int &x,int y){x=(x+y)%mod;}
int n,m,in[N],head[N],headg[N],tot,fa[N],L[N],R[N],dn,rub[N],num;
ll dis[N],ans[N];
struct EDGE{int v,next,w;}e[N<<2],g[N<<1];
inline void adde(int u,int v,int w){
	e[++tot]={v,head[u],w};head[u]=tot;
}
inline void addg(int u,int v,int w){
	g[++tot]={v,headg[u],w};headg[u]=tot;
}
bool vis[N],zhan[N<<2];
struct NODE{
	int pos;
	ll w;
	inline bool operator<(const NODE &A)const{return w>A.w;}
};
std::priority_queue<NODE> q;
inline int fan(int x){if(x&1)return x+1;else return x-1;}
inline void dij(){
	memset(dis,0x3f,sizeof(dis));
	dis[1]=0;q.push({1,0});
	while(!q.empty()){
		int u=q.top().pos;q.pop();
		if(vis[u])continue;vis[u]=1;
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].v,w=e[i].w;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				zhan[in[v]]=0;zhan[fan(in[v])]=0;
				in[v]=i;zhan[in[v]]=zhan[fan(in[v])]=1;fa[v]=u;
				if(!vis[v]){q.push({v,dis[v]});}
			}
		}
	}
}
int root[N],cnt;
struct TREE{ll res;int ls,rs;}t[N*20];
inline int NEW(){int wk=num?rub[num--]:++cnt;t[wk]={inf,0,0};return wk;}
inline void Del(int &p){t[p]={inf,0,0};rub[++num]=p;}
inline void update(int p){
	t[p].res=std::min(t[t[p].ls].res,t[t[p].rs].res);
}
inline void insert(int &p,int l,int r,int pos,ll x){
	if(!p)p=NEW();
	if(l==r){Min(t[p].res,x);return;}
	int mid=l+r>>1;if(pos<=mid)insert(t[p].ls,l,mid,pos,x);
	else insert(t[p].rs,mid+1,r,pos,x);update(p);
}
inline int merge(int a,int b,int l,int r){
	if(!a||!b)return a|b;
    if(l==r){Min(t[a].res,t[b].res);Del(b);return a;}
    int mid=l+r>>1;
    t[a].ls=merge(t[a].ls,t[b].ls,l,mid);
    t[a].rs=merge(t[a].rs,t[b].rs,mid+1,r);
    update(a);Del(b);return a;
}
inline ll query(int p,int l,int r,int L,int R){
	if(t[p].res>=inf)return inf;
	if(L>R)return inf;
	if(l>=L&&r<=R)return t[p].res;
	int mid=l+r>>1;ll res=inf;
	if(L<=mid)Min(res,query(t[p].ls,l,mid,L,R));
	if(R>mid)Min(res,query(t[p].rs,mid+1,r,L,R));
	return res;
}
inline void init(int u){
	L[u]=++dn;
	for(int i=headg[u];i;i=g[i].next)init(g[i].v);
	R[u]=dn;
}
inline void dfs(int u,ll dep){
	for(int i=headg[u];i;i=g[i].next){
		dfs(g[i].v,dep+g[i].w);
		root[u]=merge(root[u],root[g[i].v],1,n);
	}
	if(u==1)return;
	Min(ans[u],std::min(query(root[u],1,n,1,L[u]-1),query(root[u],1,n,R[u]+1,n))-dep);
	int what=std::min(query(root[u],1,n,1,L[u]-1),query(root[u],1,n,R[u]+1,n));
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].v;
		if(zhan[i]||L[v]>=L[u]&&R[v]<=R[u])continue;
		ll res=dis[v]+e[i].w;insert(root[u],1,n,L[v],res+dep);
		Min(ans[u],res);
	}
}
signed main(){
    freopen("path.in","r",stdin);freopen("path.out","w",stdout);
    // freopen("in.in","r",stdin);freopen("out.out","w",stdout);
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
    n=read(),m=read();for(int i=1;i<=m;++i){int u=read(),v=read(),w=read();adde(u,v,w);adde(v,u,w);}
    dij();tot=0;for(int i=2;i<=n;++i)addg(fa[i],i,e[in[i]].w);
	init(1);t[0].res=inf;for(int i=1;i<=n;++i)ans[i]=inf;
    dfs(1,0);
	for(int i=2;i<=n;++i)std::cout<<(ans[i]>=1e17?-1:ans[i])<<'\n';
}

标签:return,int,res,52,inline,root,CSP,模拟,dis
From: https://www.cnblogs.com/Ishar-zdl/p/18489510

相关文章

  • Qt编写的modbus模拟器/支持网络和串口以及websocket/支持网络rtu
    一、使用说明1.1设备模拟-Com第一步,填写要模拟的设备地址,0表示自动处理,也就是收到什么地址就应答什么地址。第二步,填写对应的串口号和波特率。第三步,单击打开串口,成功后会变成关闭串口字样。单击清空数据会将左侧打印栏的信息清空。右侧一堆微调框用于模拟对应设备多个寄......
  • Day10 备战CCF-CSP练习
    Day10题目描述十滴水是一个非常经典的小游戏。小\(C\)正在玩一个一维版本的十滴水游戏。我们通过一个例子描述游戏的基本规则。游戏在一个$1×c$的网格上进行,格子用整数$x(1≤x≤c)$编号,编号从左往右依次递增。网格内\(m\)个格子里有\(1∼4\)滴水,其余格子里没有......
  • CSP2024 前集训:多校A层冲刺NOIP2024模拟赛08
    前言先痛骂没良心出题人,T1\(n\sqrtn\)多大你刚好给多大,一点不多给,T2才是签到题,因为放了T2位置打了暴力就去想T3了,我是唐氏,谁让你T1、T2swap的?T3实则三道题。但是还是感觉T1更简单啊,\(5e4\)搁哪儿摆着呢一眼\(O(n\sqrtn)\),甚至空间也是这么多,太明显了。挂分挂......
  • 对于 CF,AT,CSP-S,NOIP,我想说
    尽管我是div2一题水平,但是......
  • 模拟六补题报告
    一、题目报告比赛中第一题AC,第二题0分(时间超限),第三题AC,第四题0分,比赛后全部AC。二、赛中概况首先做得第一题,第一题特别简单,用了3分钟左右;然后是第二题,三、题目正解T1 挑选苹果(apple)时间限制:1秒        内存限制:128M题目描述小可手里有n个苹果,大小为a1,......
  • 多校A层冲刺NOIP2024模拟赛09
    多校A层冲刺NOIP2024模拟赛09考试唐完了,T2、T4都挂了100分,人麻了。排列最小生成树给定一个\(1,2,\dots,n\)的排列\(p_1,p_2,\dots,p_n\)。构造一个\(n\)个点的完全无向图,节点编号分别是\(1,2,\dots,n\)。节点i和节点j之间的边边权为\(|pi−pj|×|i......
  • CSP-S前总复习
    里面大概有一两个星期吧,挑一些有价值的写。[ABC369F]GatherCoins来补的题目。先考虑不输出方案的写法。排序过后可以用一个DP实现。注意到DP的转移方程只和max有关,所以可以用数据结构优化。排序过后保证横坐标不降,所以只需要对纵坐标开一个树状数组,维护最大值,能做到......
  • MLE 5217 : Take-Home Dataset Classification
    Dept.ofMaterialsScience&EngineeringNUSMLE5217:Take-HomeAssignmentsLecturerSasaniJayawardhanaObjectivesBasedonthechemicalcompositionofmaterialsbuildaclassificationmodeltodistinguishmetalsandnon-metalsModel1),andthenb......
  • CSP 模拟 51
    A排列最小生成树(pmst)首先想到\(n^2\)建边的做法,然后最小生成树的所有边权都小于\(n\),直接从头到尾连都能轻松满足这个。所以很多边是无用的,只要找边权小于\(n\)的边即可。所以对于位置差和权值差在\(\sqrtn\)以下的都找一遍即可,然后桶排跑MST即可。赛时根号都写脸......
  • 『模拟赛』信友队2024CSP-S第二轮(复赛)模拟赛
    Rank意外地好A.坦白签。首先对\(m=0\)很好求,正着跑一遍就行。接着考虑\(m\lt0\)时什么时候遗忘会更优。发现是\(\oplus\)操作,因此答案为偶时(即事件为奇时)遗忘会使答案+1。为判断是否比原先优,我们提前处理出后缀和即可。这题关键在想出一个性质,\(m=i\)是由\(m=i-......