线段树分治+lct求卡常
查看原帖
线段树分治+lct求卡常
754502
_AyachiNene楼主2024/6/5 17:14
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace IO
{
	char buff[1<<21],*p1=buff,*p2=buff;
	char getch(){return p1==p2&&(p2=((p1=buff)+fread(buff,1,1<<21,stdin)),p1==p2)?EOF:*p1++;}
	template<typename T>void read(T &x){char ch=getch();int fl=1;x=0;while(ch>'9'||ch<'0'){if(ch=='-')fl=-1;ch=getch();}while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getch();}x*=fl;}
	template<typename T>void read_s(T &x){char ch=getch();while(ch<'a'||ch>'z')ch=getch();while(ch>='a'&&ch<='z'){x+=ch;ch=getch();}}
	template<typename T,typename ...Args>void read(T &x,Args& ...args){read(x);read(args...);}
	char obuf[1<<21],*p3=obuf;
	void putch(char ch) {if(p3-obuf<(1<<21))*p3++=ch;else fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=ch;}
	char ch[100];
	template<typename T>void write(T x) {if(!x)return putch('0');if(x<0)putch('-'),x*=-1;int top=0;while(x)ch[++top]=x%10+48,x/=10;while(top)putch(ch[top]),top--;}
	template<typename T,typename ...Args>void write(T x,Args ...args) {write(x);write(args...);}
	void put(string s){for(int i=0;i<s.size();i++)putch(s[i]);}
	void flush(){fwrite(obuf,p3-obuf,1,stdout);}
}
using namespace IO;
int n,m,k;
int ans[114514];
struct node
{
	int x,y,z,w;
}edge[114514];
namespace Elaina
{
	int stk[100005],top;
	struct fhq
	{
		int l,r,f,pre,tag,rnd;
		node val,maxn;
	}t[100005];
	inline node Max(node x,node y)
	{
		if(x.w<y.w) return y;
		return x;
	}
	inline int isroot(int p){return (t[t[p].f].l!=p&&t[t[p].f].r!=p)||!t[p].f;}
	inline void down(int p)
	{
		if(!t[p].tag) return;
		if(t[p].l) t[t[p].l].tag^=1;
		if(t[p].r) t[t[p].r].tag^=1;
		swap(t[p].l,t[p].r);
		t[p].tag=0;
	}
	inline void update(int p)
	{
		t[p].maxn=t[p].val;
		if(t[p].l) t[p].maxn=Max(t[p].maxn,t[t[p].l].maxn),t[t[p].l].f=p;
		if(t[p].r) t[p].maxn=Max(t[p].maxn,t[t[p].r].maxn),t[t[p].r].f=p;
	}
	int merge(int x,int y)
	{
		if(!x||!y) return x|y;
		down(x);down(y);
		if(t[x].rnd<t[y].rnd)
		{
			t[x].r=merge(t[x].r,y);
			update(x);
			return x;
		}
		else
		{
			t[y].l=merge(x,t[y].l);
			update(y);
			return y;
		}
	}
	void split(int p,int &x,int &y)
	{
		if(!top)
		{
			down(p);
			x=p;y=t[p].r;
			t[p].r=0;
			update(p);
			return;
		}
		int flag=stk[top--]^t[p].tag;
		down(p);
		if(!flag) x=p,split(t[p].r,t[p].r,y);
		else y=p,split(t[p].l,x,t[p].l);
		update(p);
	}
	inline int markroot(int p)
	{
		top=0;
		while(!isroot(p))
		{
			stk[++top]=(t[t[p].f].l==p);
			p=t[p].f;
		}
		return p;
	}
	inline int findroot(int p)
	{
		p=markroot(p);
		down(p);
		while(t[p].l) down(p=t[p].l);
		return p;
	}
	inline int access(int p)
	{
		int last=0;
		while(p)
		{
			int a,b;
			split(markroot(p),a,b);
			t[findroot(last)].pre=0;
			last=merge(a,last);
			t[findroot(b)].pre=p;
			p=t[findroot(last)].pre;
		}
		return last;
	}
	inline void makeroot(int p)
	{
		t[access(p)].tag^=1;
	}
	inline void link(int x,int y)
	{
		makeroot(x);
		t[x].pre=y;
	}
	inline void cut(int x,int y)
	{
		makeroot(x);
		access(y);access(x);
		t[y].pre=0;
	}
	inline node query(int x,int y)
	{
		makeroot(x);
		return t[access(y)].maxn;
	}
	inline void change(int x,int u,int v,int w)
	{
		makeroot(x);
		t[x].val=t[x].maxn=(node){u,x,v,w};
	}
	inline int check(int x,int y)
	{
		return findroot(access(x))==findroot(access(y));
	}
}
namespace Chtholly
{
	vector<pair<int,int> >t[200005];
	int now;
	pair<int,node>stk[200005];
	int top;
	#define ls (root<<1)
	#define rs (root<<1|1)
	#define mid (l+r>>1)
	void insert(int x,int y,pair<int,int>v,int l=0,int r=k,int root=1)
	{
		if(l>=x&&r<=y)
		{
			t[root].push_back(v);
			return;
		}
		if(x<=mid) insert(x,y,v,l,mid,ls);
		if(y>mid) insert(x,y,v,mid+1,r,rs);
	}
	void solve(int l=0,int r=k,int root=1)
	{
		int tmp=now,tmpt=top;
		for(int i=0;i<t[root].size();i++)
		{
			int id=t[root][i].first;
			int u=edge[id].x,v=edge[id].y,w=t[root][i].second;
			if(!Elaina::check(u,v))
			{
				now+=w;
				Elaina::link(u,id+n);Elaina::link(v,id+n);
				Elaina::change(id+n,u,v,w);
				stk[++top]=make_pair(0,(node){u,id+n,v,0});
			}
			else
			{
				node p=Elaina::query(u,v);
				if(p.w>w)
				{
					now+=w-p.w;
					stk[++top]=make_pair(1,(node){p.x,p.y,p.z,p.w});
					Elaina::cut(p.x,p.y);Elaina::cut(p.y,p.z);
					Elaina::link(u,p.y);Elaina::link(p.y,v);
					Elaina::change(p.y,u,v,w);
					stk[++top]=make_pair(0,(node){u,p.y,v,0});
				}
			}
		}
		if(l==r) ans[l]=now;
		if(l!=r) solve(l,mid,ls),solve(mid+1,r,rs);
		now=tmp;
		while(top>tmpt)
		{
			if(!stk[top].first)
			{
				Elaina::cut(stk[top].second.x,stk[top].second.y);
				Elaina::cut(stk[top].second.y,stk[top].second.z);
				Elaina::change(stk[top].second.y,0,0,0);
			}
			else
			{
				Elaina::link(stk[top].second.x,stk[top].second.y);
				Elaina::link(stk[top].second.y,stk[top].second.z);
				Elaina::change(stk[top].second.y,stk[top].second.x,stk[top].second.z,stk[top].second.w);
			}
			--top;
		}
	}
}
int last[114514];
signed main()
{
	srand(time(NULL));
	read(n,m,k);
	for(int i=1;i<=1e5;i++) Elaina::t[i].rnd=rand();
	for(int i=1;i<=m;i++)
	{
		int u,v,w;
		read(u,v,w);
		edge[i].x=u;edge[i].y=v;edge[i].w=w;
	}
	for(int i=1;i<=k;i++)
	{
		int id,w;
		read(id,w);
		Chtholly::insert(last[id],i-1,make_pair(id,edge[id].w));
		edge[id].w=w;
		last[id]=i;
	}
	for(int i=1;i<=m;i++) Chtholly::insert(last[i],k,make_pair(i,edge[i].w));
	Chtholly::solve();
	for(int i=1;i<=k;i++) write(ans[i]),putch('\n');
	flush();
}
2024/6/5 17:14
加载中...