P5163-WD与地图【tarjan,整体二分,线段树合并】

正题

题目链接:https://www.luogu.com.cn/problem/P5163


题目大意

给出nnn个点mmm条有向边,点有权值,要求支持操作

  1. 删除一条边
  2. 修改一个点的权值
  3. 求一个点所在强连通分量中前kkk大权值和

1≤n≤105,1≤m,q≤2×1051\leq n\leq 10^5,1\leq m,q\leq 2\times 10^51n105,1m,q2×105


解题思路

首先删边肯定是时光倒流改成加边,然后考虑怎么继续做。

我们需要处理一些点集什么时候合并,这样的合并其实不会超过n−1n-1n1次。

而且每次肯定是合并某条边(x,y)(x,y)(x,y)两个点所在的强连通分量,但是每次加入的一条边(x,y)(x,y)(x,y)不一定会即使生效。
我们可以考虑对于每条边求出它在后来加入哪条边加入之后生效了,这个可以考虑整体二分,我们每次把所有询问的边集在[0,mid][0,mid][0,mid]区间的边加入然后跑tarjantarjantarjan,把跑出来的强连通分量缩成一个点然后继续丢到右边跑,跑完右边的子区间之后再撤销这次tarjantarjantarjan缩起来的点然后跑左边。

这样一定是对的因为如果一条答案不在这个区间的边生效,那么它要不就在之前被合并了要么在这个区间内都合并不了,所以没有作用。

这个要用一个可撤销并查集,记得安秩合并就好了。

之后我们就有一个操作变成合并两个集合了,线段树合并做剩下的部分就行了

时间复杂度O(nlog⁡2n)O(n\log^2 n)O(nlog2n)(反正差不多同级就不写这么详细了在这里插入图片描述


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#define ll long long
#define mp(x,y) make_pair(x,y)
using namespace std;
const ll N=8e5+10;
struct node{ll to,next;
}a[N];
struct enode{ll x,y,t,T;
}e[N],p1[N],p2[N];
struct qnode{ll x,k;
}q[N];
struct snode{ll x,y,fa,dep;
}st[N];
ll n,m,t,tot,snt,clt,cnt,s[N];
ll ls[N],fa[N],dep[N],cl[N];
ll dfn[N],low[N],rt[N],ans[N];
bool ins[N];stack<ll> S;
map<pair<ll,ll> ,ll> emp;
void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
ll find(ll x)
{return (fa[x]==x)?x:find(fa[x]);}
ll Find(ll x)
{return (fa[x]==x)?x:(fa[x]=Find(fa[x]));}
void unionn(ll x,ll y){x=find(x);y=find(y);if(x==y)return;if(dep[x]>dep[y])swap(x,y);st[++snt]=(snode){x,y,fa[x],dep[y]};fa[x]=y;dep[y]=max(dep[y],dep[x]+1);
}
void clearto(ll z){while(snt>z){dep[st[snt].y]=st[snt].dep;fa[st[snt].x]=st[snt].fa;snt--;}return;
}
void tarjan(ll x){dfn[x]=low[x]=++cnt;S.push(x);ins[x]=1;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(!dfn[y]){tarjan(y);low[x]=min(low[x],low[y]);}else if(ins[y])low[x]=min(low[x],dfn[y]);}if(low[x]==dfn[x]){while(S.top()!=x){unionn(S.top(),x);ins[S.top()]=0;S.pop();}ins[x]=0;S.pop();}return;
}
void solve(ll l,ll r,ll L,ll R){if(L>R)return;if(l==r){for(ll i=L;i<=R;i++)e[i].T=l;return;}ll mid=(l+r)>>1,zt=snt;for(ll i=L;i<=R;i++)if(e[i].t<=mid){ll x=find(e[i].x),y=find(e[i].y);addl(x,y);cl[++clt]=x;cl[++clt]=y;}cnt=tot=0;for(ll i=1;i<=clt;i++)if(!dfn[cl[i]])tarjan(cl[i]);ll t1=0,t2=0;for(ll i=L;i<=R;i++){ll x=find(e[i].x),y=find(e[i].y);if(x==y)p1[++t1]=e[i];else p2[++t2]=e[i];}for(ll i=1;i<=t1;i++)e[L+i-1]=p1[i];for(ll i=1;i<=t2;i++)e[L+t1+i-1]=p2[i];while(clt)ls[cl[clt]]=dfn[cl[clt]]=low[cl[clt]]=0,clt--;solve(mid+1,r,L+t1,R);clearto(zt);solve(l,mid,L,L+t1-1);return;
}
bool cmp(enode x,enode y)
{return x.t<y.t;}
struct SegTree{ll cnt,w[N<<5],s[N<<5],ls[N<<5],rs[N<<5];void Change(ll &x,ll L,ll R,ll pos,ll val){if(!x)x=++cnt;w[x]+=val;s[x]+=pos*val;if(L==R)return;ll mid=(L+R)>>1;if(pos<=mid)Change(ls[x],L,mid,pos,val);else Change(rs[x],mid+1,R,pos,val);return;}ll Ask(ll x,ll L,ll R,ll k){if(k>=w[x])return s[x];if(L==R)return L*k;ll mid=(L+R)>>1;if(w[rs[x]]>=k)return Ask(rs[x],mid+1,R,k);return s[rs[x]]+Ask(ls[x],L,mid,k-w[rs[x]]);}ll Merge(ll x,ll y){if(!x||!y)return x+y;w[x]=w[x]+w[y];s[x]=s[x]+s[y];ls[x]=Merge(ls[x],ls[y]);rs[x]=Merge(rs[x],rs[y]);return x;}
//	ll Merge(ll x,ll y,ll L,ll R){
//		if(!x||!y)return x+y;
//		w[x]=w[x]+w[y];
//		if(L==R)return x;
//		ll mid=(L+R)>>1;
//		ls[x]=Merge(ls[x],ls[y],L,mid);
//		rs[x]=Merge(rs[x],rs[y],mid+1,R);
//		return x;
//	}
}T;
void Merge(ll x,ll y){x=Find(x),y=Find(y);if(x==y)return;rt[x]=T.Merge(rt[x],rt[y]);fa[y]=x;return;
}
signed main()
{scanf("%lld%lld%lld",&n,&m,&t);for(ll i=1;i<=n;i++)scanf("%lld",&s[i]),fa[i]=i;for(ll i=1;i<=m;i++){scanf("%lld%lld",&e[i].x,&e[i].y);emp[mp(e[i].x,e[i].y)]=i;}for(ll i=t;i>=1;i--){ll op,x,y;scanf("%lld%lld%lld",&op,&x,&y);if(op==1)e[emp[mp(x,y)]].t=i;else if(op==2)q[i].x=-x,q[i].k=y,s[x]+=y;else if(op==3)q[i].x=x,q[i].k=y;}sort(e+1,e+1+m,cmp);solve(0,t+1,1,m);ll z=1;for(ll i=1;i<=n;i++)fa[i]=i,T.Change(rt[i],1,1e9,s[i],1);for(ll i=1;i<=t;i++){while(z<=m&&e[z].T<=i)Merge(e[z].x,e[z].y),z++;if(q[i].x<0){ll x=-q[i].x,w=q[i].k,f=Find(x);T.Change(rt[f],1,1e9,s[x],-1);s[x]-=w;T.Change(rt[f],1,1e9,s[x],1);}else if(q[i].x>0){ll x=Find(q[i].x),k=q[i].k;ans[i]=T.Ask(rt[x],1,1e9,k);}}for(ll i=t;i>=1;i--)if(ans[i])printf("%lld\n",ans[i]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式系统(微服务架构)的一致性和幂等性问题相关概念解析

前言什么是分布式系统?关于这点其实并没有明确且统一的定义。在我看来,只要一个系统满足以下几点就可以称之为分布式系统系统由物理上不同分布的多个机器节点组成系统的多个节点通过网络进行通信,协调彼此之间的工作。系统作为整体统一对外提供服务,其分布式细节对客户端透明。…

hash:奶牛看地图(洛谷P3405 [USACO16DEC]Cities and States S)

洛谷传送门 解析 其实就是每组2个长度为2的字符串统计交叉相等的个数 每个序列可以用一个26进制的数来表示&#xff0c;总要加个标签&#xff0c;勉强算hash。。&#xff08;想叫《水题》 &#xff09; 最大值为26*26&#xff08;ZZ&#xff09; 所以可以开一个二维数组来进…

牛客题霸 [两个链表的第一个公共结点] C++题解/答案

牛客题霸 [两个链表的第一个公共结点] C题解/答案 题目描述 输入两个链表&#xff0c;找出它们的第一个公共结点。&#xff08;注意因为传入数据是链表&#xff0c;所以错误测试数据的提示是用其他方式显示的&#xff0c;保证传入数据是正确的&#xff09; 题解&#xff1a;…

L. Mod(预处理+分块)

L.Mod 题目大意 给定一个序列和 l,r,kl,r, kl,r,k&#xff0c;询问 [l,r][l,r][l,r] 中的数字 mod kkk 的最大值,1≤n,k≤500001\leq n,k\leq 500001≤n,k≤50000 分块&#xff0c;预处理fi,jf_{i,j}fi,j​表示第iii块mod jjj的最大值。 对于每一块&#xff0c;维护 mximx_i…

AT2667-[AGC017D]Game on Tree【SG函数】

正题 题目链接:https://www.luogu.com.cn/problem/AT2667 题目大意 给出nnn个点的一棵树&#xff0c;每次可以割掉一条和根节点联通的边&#xff0c;轮流操作直到不能操作的输&#xff0c;求是否先手必胜。 1≤n≤21051\leq n\leq 2\times 10^51≤n≤2105 解题思路 挺巧妙的…

bfs:01迷宫(洛谷P1141)

洛谷传送门 解析 乍一看&#xff1a;bfs板子题 冰法师最棒了 然鹅 看了一眼数据范围 心中已有画面 《面 堂 发 黑》 怎么办嘞&#xff1f; 我们想到&#xff1a; 因为该题来与去的可逆性 我们搜一次后&#xff0c;这些点以后都不会再用到 而且每次覆盖到的所有点答案都是…

有关C# 8.0、.NET Framework 4.8与NET Standard 2.1的一个说明

早在本月12日&#xff0c;微软官方的.NET Blog发布了一篇名为《Building C# 8.0》的文章&#xff0c;介绍了很多C# 8.0的新特性。不过本文主要讨论的并不是C# 8.0的新特性&#xff0c;而是存在于这篇文章中的一段文字&#xff1a;Most of the C# 8.0 language features will ru…

2021牛客暑期多校训练营1 J-Journey among Railway Stations(线段树+思维转化)

J-Journey among Railway Stations 注意区间合并时是否可行信息的合并。 假设线段树当前左节点lll维护的区间是[L,mid][L,\text{mid}][L,mid]&#xff0c;右节点维护的区间为[mid1,R][\text{mid1},R][mid1,R] 如果它们分别可行&#xff0c;意味着可以从L→midL\to \text{mid}…

牛客题霸 [括号序列] C++题解/答案

牛客题霸 [括号序列] C题解/答案 题目描述 给出一个仅包含字符’(’,’)’,’{’,’}’,’[‘和’]’,的字符串&#xff0c;判断给出的字符串是否是合法的括号序列 括号必须以正确的顺序关闭&#xff0c;"()“和”()[]{}“都是合法的括号序列&#xff0c;但”(]“和”([…

P3964-[TJOI2013]松鼠聚会【计算几何】

正题 题目链接:https://www.luogu.com.cn/problem/P3964 题目大意 给出nnn个点&#xff0c;求一个点使得它到所有点的切比雪夫距离和最小。 0≤n≤105,−109≤xi,yi≤1090\leq n\leq 10^5,-10^9\leq x_i,y_i\leq 10^90≤n≤105,−109≤xi​,yi​≤109 解题思路 额切比雪夫距…

领域驱动设计,让程序员心中有码

“ 领域驱动设计的背后&#xff0c;需要开发者不能只专注于眼前功能的实现&#xff0c;而应该能够从全局去了解业务&#xff0c;并充分的将业务吃透&#xff0c;以可传承的知识的形式融入到开发过程中&#xff0c;只有这样才能促进产品更好的开发。”01—传统项目管理模式&…

模板:快读

我也学会快读了~~~ 没啥可讲的 注意对负号的处理 int input () {int x 0, f 0;char c getchar ();while (c < 0 || c > 9) f c -, c getchar ();while (c > 0 && c < 9) x (x << 1) (x << 3) (c ^ 48), c getchar ();return f ? -…

codeforces1553 F. Pairwise Modulo(数学)

F. Pairwise Modulo 想到了&#xff0c;但又没完全想到。。wtcl 首先 pkpk−1∑1≤i<kakmodai∑1≤i<kaimodakp_kp_{k-1}\sum_{1\leq i<k} a_k \bmod \ a_i\sum_{1\leq i<k} a_i \bmod \ a_kpk​pk−1​∑1≤i<k​ak​mod ai​∑1≤i<k​ai​mod ak​ ∑1≤…

牛客题霸 [寻找第K大] C++题解/答案

牛客题霸 [寻找第K大] C题解/答案 题目描述 有一个整数数组&#xff0c;请你根据快速排序的思路&#xff0c;找出数组中第K大的数。 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间)&#xff0c;请返回第K大的数&#xff0c;保证答案存在。 题目&#xff1a; …

Loj#6247-九个太阳【单位根反演】

正题 题目链接:https://loj.ac/p/6247 题目大意 给出n,kn,kn,k求 ∑0≤i≤n,i∣k(ni)\sum_{0\leq i\leq n,i|k}\binom{n}{i}0≤i≤n,i∣k∑​(in​) 对998244353998244353998244353取模 1≤n≤1015,1≤k≤220,k2p(p∈N)1\leq n\leq 10^{15},1\leq k\leq 2^{20},k2^p(p\in N)1…

Docker最全教程——从理论到实战(二)

容器是应用走向云端之后必然的发展趋势&#xff0c;因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。本篇教程持续编写了2个星期左右&#xff0c;只是为了大家更好地了解、理解和消化这个技术&#xff0c;能够搭上这波车。你可以关注我们的公众号“magiccode…

图论模板详解:存图

图论千万条&#xff0c;存图第一条 1.邻接矩阵 用一个矩阵x[i][j]表示i到j的路径 优点&#xff1a;代码方便&#xff0c;易于去重 缺点&#xff1a;空间复杂度爆炸 优化&#xff1a;二维vector&#xff08;但是会变慢&#xff09; 2.链式前向星 &#xff08;抄资料毫不掩饰&a…

2021牛客暑期多校训练营3 C-Minimum grid(二分图)

C-Minimum grid 如果第iii行最大值是aaa&#xff0c;第jjj列最大值是ccc&#xff0c;我们需要第iii行单独有一个格子权值是aaa&#xff0c;而且第jjj列单独有一个格子权值是bbb&#xff0c;不过如果第iii行最大值和第jjj列最大值是都是aaa&#xff0c;那么我们只需让第iii行第…

牛客题霸 [ 在二叉树中找到两个节点的最近公共祖先] C++题解/答案

牛客题霸 [ 在二叉树中找到两个节点的最近公共祖先] C题解/答案 题目描述 给定一棵二叉树以及这棵树上的两个节点 o1 和 o2&#xff0c;请找到 o1 和 o2 的最近公共祖先节点。 题解&#xff1a; 我们想想最近公共祖先节点满足什么要求&#xff1f;&#xff1f; o1和o2分别位…

P4249-[WC2007]剪刀石头布【费用流】

正题 题目链接:https://www.luogu.com.cn/problem/P4249 题目大意 nnn个点的竞赛图有的边已经确定了方向&#xff0c;要求给剩下的边确定一个方向使得图的三元环最多。 1≤n≤1001\leq n\leq 1001≤n≤100 解题思路 竞赛图如果三个点不能构成三元环有一个性质就是恰好有一个点…