线段树优化建树 CF786B
看到区间操作想到用线段树优化建树,建一棵外向树一棵内向树,用线段树点代表整个区间内的所有点。
从树上找节点然后连边就可以,最后跑个dijktra就完成了。
我一次就过样例了,改了几次内存就过了这题,太好了!!!
#include <bits/stdc++.h> #define ll long long #define int ll #define ls p<<1 #define rs p<<1|1 #define re register #define pb push_back #define pir pair<int,int> #define f(a,x,i) for(int i=a;i<=x;i++) #define fr(a,x,i) for(int i=a;i>=x;i--) #define lb(x) x&(-x); using namespace std; const int N=1e6+10; const int M=8e6+10; const int mod=1e9+7; int n,q,s; int cnt; struct sss{ int v,w; }; vector<sss> a[N]; struct ss{ int l,r,id; }t1[N<<1],t2[N<<1]; int top1,top2; int build1(int p,int l,int r){ if(l==r){ return t1[l].id; } t1[p].id=p; int mid=(l+r)>>1; t1[p].l=build1(++cnt,l,mid); t1[p].r=build1(++cnt,mid+1,r); a[p].push_back({t1[p].l,0}); a[p].push_back({t1[p].r,0}); return p; } int build2(int p,int l,int r){ if(l==r){ return t2[l].id; } t2[p].id=p; int mid=(l+r)>>1; t2[p].l=build2(++cnt,l,mid); t2[p].r=build2(++cnt,mid+1,r); a[t2[p].l].push_back({p,0}); a[t2[p].r].push_back({p,0}); return p; } void change1(int p,int pl,int pr,int l,int r,int x,int w){ if(pl>=l&&pr<=r){ a[x].push_back({p,w}); return; } int mid=(pl+pr)>>1; if(l<=mid) change1(t1[p].l,pl,mid,l,r,x,w); if(r>mid) change1(t1[p].r,mid+1,pr,l,r,x,w); } void change2(int p,int pl,int pr,int l,int r,int x,int w){ if(pl>=l&&pr<=r){ a[p].push_back({x,w}); return; } int mid=(pl+pr)>>1; if(l<=mid) change2(t2[p].l,pl,mid,l,r,x,w); if(r>mid) change2(t2[p].r,mid+1,pr,l,r,x,w); } int dis[N]; int vis[N]; void dijkstra(int s){ for(int i=1;i<=cnt;i++) dis[i]=1e18; dis[s]=0; priority_queue<pir,vector<pir>,greater<pir> > q; q.push({0,s}); while(!q.empty()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(auto i:a[u]){ int v=i.v; int w=i.w; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; q.push({dis[v],v}); } } } } signed main(){ ios::sync_with_stdio(0); cin.tie(nullptr); cin>>n>>q>>s; for(int i=1;i<=n;i++){ t1[i].id=i; t2[i].id=i+n; a[i].push_back({i+n,0}); a[i+n].push_back({i,0}); } cnt=2*n; top1=build1(++cnt,1,n); top2=build2(++cnt,1,n); for(int i=1;i<=q;i++){ int op,u,v,w,l,r; cin>>op; if(op==1){ cin>>u>>v>>w; a[u].push_back({v,w}); } else if(op==2){ cin>>u>>l>>r>>w; change1(top1,1,n,l,r,u+n,w); } else{ cin>>u>>l>>r>>w; change2(top2,1,n,l,r,u,w); } } dijkstra(s); for(int i=1;i<=n;i++){ if(dis[i]==1e18) cout<<"-1 "; else cout<<dis[i]<<" "; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具