一个很显然的思路是把边按时间段拆开线段树分治一下,用lct维护MST。理论上复杂度是O((M+Q)logNlogQ),实际常数爆炸T成狗。正解写不动了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 20010
#define M 50010
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
#define lself tree[tree[k].fa].ch[0]
#define rself tree[tree[k].fa].ch[1]
int n,m,q,f[M],L[M<<],R[M<<],cnt;
long long tot=,ans[M];
struct edge{int x,y,z;
}e[M],a[N+M<<];
struct data{int i,x;};
vector<data> Q[M];
vector<int> tree[M<<];
stack<int> undo[M<<];
namespace lct
{
struct data{int ch[],fa,rev,x;}tree[N+M<<];
void up(int k)
{
tree[k].x=k;
if (a[tree[lson].x].z>a[tree[k].x].z) tree[k].x=tree[lson].x;
if (a[tree[rson].x].z>a[tree[k].x].z) tree[k].x=tree[rson].x;
}
void rev(int k){if (k) swap(lson,rson),tree[k].rev^=;}
void down(int k){if (tree[k].rev) rev(lson),rev(rson),tree[k].rev=;}
bool isroot(int k){return lself!=k&&rself!=k;}
int whichson(int k){return rself==k;}
void push(int k){if (!isroot(k)) push(tree[k].fa);down(k);}
void move(int k)
{
int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);
if (!isroot(fa)) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;
tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa;
tree[fa].fa=k,tree[k].ch[!p]=fa;
up(fa),up(k);
}
void splay(int k)
{
push(k);
while (!isroot(k))
{
int fa=tree[k].fa;
if (!isroot(fa))
if (whichson(fa)^whichson(k)) move(k);
else move(fa);
move(k);
}
}
void access(int k){for (int t=;k;t=k,k=tree[k].fa) splay(k),tree[k].ch[]=t,up(k);}
void makeroot(int k){access(k),splay(k),rev(k);}
int findroot(int k){access(k),splay(k);for (;lson;k=lson) down(k);splay(k);return k;}
void link(int x,int y){makeroot(x);tree[x].fa=y;}
void cut(int x,int y){makeroot(x),access(y),splay(y);tree[y].ch[]=tree[x].fa=;up(y);}
int query(int x,int y){makeroot(x),access(y),splay(y);return tree[y].x;}
void newpoint(int k){tot+=a[k].z;link(k,a[k].x),link(k,a[k].y);}
void delpoint(int k){tot-=a[k].z;cut(k,a[k].x),cut(k,a[k].y);}
}
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;
if (l==r) return;
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
}
void add(int k,int l,int r,int e)
{
if (L[k]==l&&R[k]==r) {tree[k].push_back(e);return;}
int mid=L[k]+R[k]>>;
if (r<=mid) add(k<<,l,r,e);
else if (l>mid) add(k<<|,l,r,e);
else add(k<<,l,mid,e),add(k<<|,mid+,r,e);
}
void solve(int k)
{
int s=tree[k].size();
for (int i=;i<s;i++)
if (lct::findroot(a[tree[k][i]].x)!=lct::findroot(a[tree[k][i]].y))
lct::newpoint(tree[k][i]),undo[k].push(tree[k][i]);
else
{
int t=lct::query(a[tree[k][i]].x,a[tree[k][i]].y);
if (a[t].z>a[tree[k][i]].z)
{
lct::delpoint(t),lct::newpoint(tree[k][i]);
undo[k].push(-t),undo[k].push(tree[k][i]);
}
}
if (L[k]==R[k]) ans[L[k]]=tot;
else solve(k<<),solve(k<<|);
while (!undo[k].empty())
{
if (undo[k].top()<) lct::newpoint(-undo[k].top());
else lct::delpoint(undo[k].top());
undo[k].pop();
}
}
int main()
{
freopen("bzoj2001.in","r",stdin);
freopen("bzoj2001.out","w",stdout);
n=read(),m=read(),q=read();
for (int i=;i<=m;i++)
e[i].x=read(),e[i].y=read(),e[i].z=read();
for (int i=;i<=q;i++)
{
int x=read(),y=read();
Q[x].push_back((data){i,y});
}
build(,,q);
cnt=n;
for (int i=;i<=m;i++)
{
int s=Q[i].size();
if (s==) a[++cnt]=e[i],add(,,q,cnt);
else
{
if (Q[i][].i>) a[++cnt]=e[i],add(,,Q[i][].i-,cnt);
for (int j=;j<s-;j++)
a[++cnt]=(edge){e[i].x,e[i].y,Q[i][j].x},
add(,Q[i][j].i,Q[i][j+].i-,cnt);
a[++cnt]=(edge){e[i].x,e[i].y,Q[i][s-].x},
add(,Q[i][s-].i,q,cnt);
}
}
solve();
for (int i=;i<=q;i++) printf("%lld\n",ans[i]);
fclose(stdin);fclose(stdout);
return ;
}

BZOJ2001 HNOI2010城市建设(线段树分治+LCT)的更多相关文章

  1. P3206 [HNOI2010]城市建设 [线段树分治+LCT维护动态MST]

    Problem 这题呢 就边权会在某一时刻变掉-众所周知LCT不支持删边的qwq- 所以考虑线段树分治- 直接码一发 如果 R+1 这个时间修改 那就当做 [L,R] 插入了一条边- 然后删的边和加的 ...

  2. 【BZOJ2001】[HNOI2010]城市建设(CDQ分治,线段树分治)

    [BZOJ2001][HNOI2010]城市建设(CDQ分治,线段树分治) 题面 BZOJ 洛谷 题解 好神仙啊这题.原来想做一直不会做(然而YCB神仙早就切了),今天来怒写一发. 很明显这个玩意换种 ...

  3. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  4. 【洛谷P4319】 变化的道路 线段树分治+LCT

    最近学了一下线段树分治,感觉还蛮好用... 如果正常动态维护最大生成树的话用 LCT 就行,但是这里还有时间这一维的限制. 所以,我们就把每条边放到以时间为轴的线段树的节点上,然后写一个可撤销 LCT ...

  5. BZOJ2001 HNOI2010 城市建设

    题目大意:动态最小生成树,可以离线,每次修改后回答,点数20000,边和修改都是50000. 顾昱洲是真的神:顾昱洲_浅谈一类分治算法 链接: https://pan.baidu.com/s/1c2l ...

  6. 【CDQ分治】[HNOI2010]城市建设

    题目链接 线段树分治+LCT只有80 然后就有了CDQ分治的做法 把不可能在生成树里的扔到后面 把一定在生成树里的扔到并查集里存起来 分治到l=r,修改边权,跑个kruskal就行了 由于要支持撤销, ...

  7. 【LG3206】[HNOI2010]城市建设

    [LG3206][HNOI2010]城市建设 题面 洛谷 题解 有一种又好想.码得又舒服的做法叫线段树分治+\(LCT\) 但是因为常数过大,无法跑过此题. 所以这里主要介绍另外一种玄学\(cdq\) ...

  8. LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset

    题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...

  9. LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治

    题目:https://loj.ac/problem/121 离线,LCT维护删除时间最大生成树即可.注意没有被删的边的删除时间是 m+1 . 回收删掉的边的节点的话,空间就可以只开 n*2 了. #i ...

随机推荐

  1. Linux 安装erlang

    安装rabbitmq的基础erlang1. 下载erlang 版本:otp_src_20.1.tar.gz 地址: http://erlang.org/download/?M=D 2.安装erlang ...

  2. SQL Server如何更改系统用户dbo的所属账号

    在SQL Server的每个数据库中都有一个dbo系统用户,dbo是系统默认创建的,无法被删除,如下: dbo在内部其实是绑定了一个SQL Server账号的,可以通过其属性查看Login name, ...

  3. 图解IIS8上解决网站第一次访问慢的处理(转载)

    本篇经验以IIS8,Windows Server 2012R2做为案例.IIS8 运行在 Windows Server 2012 and Windows 8 版本以上的平台上.IIS中应用程序池和网站 ...

  4. JavaWeb开发中采用FreeMarker生成Excel表格

            最近做了一个需求,要求导出一个采购合同的Excel表格,这个表格样式比较多.由于是合同,这个Excel表格里面有好多格式要求,比如结尾处签字那部分就有格式要求.这里介绍种采用FreeM ...

  5. Luogu P3959 宝藏

    这道题正解是状压DP,不过我不会所以写一下随机化算法来骗骗分. 听说当时考场上就有很多写prim然后挂掉的神仙,其实这道题是可以prim过的 prim是一种基于贪心的算法,在本题中由于盲目的选择当前最 ...

  6. linux 下隐藏进程的一种方法

    前言 本文所用到的工具在 https://github.com/gianlucaborello/libprocesshider 可以下载 思路就是利用 LD_PRELOAD 来实现系统函数的劫持 LD ...

  7. 【福利】送Spark大数据平台视频学习资料

    没有套路真的是送!! 大家都知道,大数据行业spark很重要,那话我就不多说了,贴心的大叔给你找了份spark的资料.   多啰嗦两句,一个好的程序猿的基本素养是学习能力和自驱力.视频给了你们,能不能 ...

  8. 用 Python 分析咪蒙1013篇文章,她凭什么会火?

    咪蒙 文学硕士,驾驭文字能力极强.并且是一个拥有一千多万粉丝,每篇文章阅读量都   100W+,头条发个软文都能赚 80 万,永远都能抓住粉丝G点的那个女人. 1月份因为某篇文章,在网络上被一大批网友 ...

  9. WPF制作带明细的环形图表

    效果 明细用Popup实现的,录gif时,Popup显示不出来,不知道为什么,所以静态图凑合看吧 大体思路 图表使用Arc+Popup实现 图表分为两部分,一是环形部分,一是标注的明细部分. 环形部分 ...

  10. TRIO-basic指令--九九乘法表demo

    在路上闲的没事,想到之前自己用别的语言实现乘法口诀表,于是来了兴趣用TRIO-basic试一下,挺简单的一段代码,大家看看就好. ' TRIO-basic '实现乘法口诀表 定义两个整型的局部变量 D ...