【CDQ分治】[HNOI2010]城市建设
线段树分治+LCT只有80
然后就有了CDQ分治的做法
把不可能在生成树里的扔到后面
把一定在生成树里的扔到并查集里存起来
分治到l=r,修改边权,跑个kruskal就行了
由于要支持撤销,并查集要按秩合并
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=2e4+5;
const int MAXM=5e4+5;
const int INF=1e9;
int n,m,q,t,ct,p;
int f[MAXN],mxdp[MAXN];
long long sum;
long long ans[MAXM];
bool vis[MAXM];
int v[MAXM];
struct rpg{
int ls,nx,ln,id,kd;
}a[MAXM],st[MAXM];
struct vx{
int id,val;
}w[MAXM];
struct fx{
int x,fx,kd;
}stk[MAXM];
int read()
{
int x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x;
}
int find(int x){return f[x]==x?x:find(f[x]);}
bool cmp1(rpg a,rpg b){return a.ln<b.ln;}
bool cmp2(rpg a,rpg b){return a.kd<b.kd;}
void un(int fa,int fb)
{
if(mxdp[fa]>mxdp[fb]) swap(fa,fb);
if(mxdp[fa]==mxdp[fb]) stk[++ct]=(fx){fa,fb,1},++mxdp[fb];
else stk[++ct]=(fx){fa,fb,0};
f[fa]=fb;
}
long long calc(int d,int t2)
{
for(int i=1;i<=t;++i){
if(a[i].id==w[d].id){
st[w[d].id].ln=a[i].ln=w[d].val;
break;
}
}sort(a+1,a+t+1,cmp1);
long long s=0;
for(int i=1;i<=t;++i){
int fa=find(a[i].ls),fb=find(a[i].nx);
if(fa!=fb) un(fa,fb),s+=a[i].ln;
}while(ct>t2){
if(stk[ct].kd) --mxdp[stk[ct].fx];
f[stk[ct].x]=stk[ct].x;
--ct;
}return sum+s;
}
void C(int t2)
{
for(int i=1;i<=t;++i) if(vis[a[i].id]) a[i].ln=INF;
sort(a+1,a+t+1,cmp1);
for(int i=1;i<=t&&a[i].ln<INF;++i){
int fa=find(a[i].ls),fb=find(a[i].nx);
if(fa!=fb) un(fa,fb);
else a[i].kd=2;
}sort(a+1,a+t+1,cmp2);
while(t&&a[t].kd) --t;
while(ct>t2){
if(stk[ct].kd) --mxdp[stk[ct].fx];
f[stk[ct].x]=stk[ct].x;
--ct;
}return;
}
void D(int t2)
{
for(int i=1;i<=t;++i) if(vis[a[i].id]) a[i].ln=-INF;
sort(a+1,a+t+1,cmp1);
for(int i=1;i<=t;++i){
int fa=find(a[i].ls),fb=find(a[i].nx);
if(fa!=fb){
un(fa,fb);
if(a[i].ln>-INF) a[i].kd=1,sum+=a[i].ln;
}
}sort(a+1,a+t+1,cmp2);
while(t&&a[t].kd) --t;
while(ct>t2){
if(stk[ct].kd) --mxdp[stk[ct].fx];
f[stk[ct].x]=stk[ct].x;
--ct;
}return;
}
void reD(int t2)
{
while(ct>t2){
if(stk[ct].kd) --mxdp[stk[ct].fx];
f[stk[ct].x]=stk[ct].x;
--ct;
}return;
}
void reC(int t1)
{
for(int i=t+1;i<=t1;++i){
if(a[i].kd==1) sum-=a[i].ln;
a[i].kd=0;
}t=t1;
return;
}
void CDQ(int l,int r)
{
if(l==r){ans[l]=calc(l,ct);return;}
int ctp=t,cmd=ct,mid=l+r>>1;
for(int i=1;i<=t;++i) vis[a[i].id]=0;
for(int i=l;i<=r;++i) vis[w[i].id]=1;
C(cmd),D(cmd);
for(int i=t+1;i<=ctp;++i) if(a[i].kd==1) un(find(a[i].ls),find(a[i].nx));
for(int i=1;i<=t;++i) a[i].ln=st[a[i].id].ln;
CDQ(l,mid),CDQ(mid+1,r);
reC(ctp);reD(cmd);
return;
}
int main()
{
n=read(),t=m=read(),q=read();
for(int i=1;i<=n;++i) f[i]=i;
for(int i=1;i<=m;++i) a[i].ls=read(),a[i].nx=read(),a[i].ln=read(),a[i].id=i,st[i]=a[i];
for(int i=1;i<=q;++i) w[i].id=read(),w[i].val=read();
CDQ(1,q);for(int i=1;i<=q;++i) printf("%lld\n",ans[i]);
return 0;
}
【CDQ分治】[HNOI2010]城市建设的更多相关文章
- 【BZOJ2001】[HNOI2010]城市建设(CDQ分治,线段树分治)
[BZOJ2001][HNOI2010]城市建设(CDQ分治,线段树分治) 题面 BZOJ 洛谷 题解 好神仙啊这题.原来想做一直不会做(然而YCB神仙早就切了),今天来怒写一发. 很明显这个玩意换种 ...
- [HNOI2010]城市建设
[HNOI2010]城市建设 玄学cdq O(nlog^2n)的动态最小生成树 其实就是按照时间cdq分治+剪枝(剪掉一定出现和不可能出现的边) 处理[l,r]之间的修改以及修改之后的询问,不能确定是 ...
- 【LG3206】[HNOI2010]城市建设
[LG3206][HNOI2010]城市建设 题面 洛谷 题解 有一种又好想.码得又舒服的做法叫线段树分治+\(LCT\) 但是因为常数过大,无法跑过此题. 所以这里主要介绍另外一种玄学\(cdq\) ...
- Luogu 3206 [HNOI2010]城市建设
BZOJ 2001 很神仙的cdq分治 先放论文的链接 顾昱洲_浅谈一类分治算法 我们考虑分治询问,用$solve(l, r)$表示询问编号在$[l, r]$时的情况,那么当$l == r$的时候 ...
- 洛谷P3206 [HNOI2010]城市建设
神仙题 题目大意: 有一张\(n\)个点\(m\)条边的无向联通图,每次修改一条边的边权,问每次修改之后这张图的最小生成树权值和 话说是不是\(cdq\)题目都可以用什么数据结构莽过去啊-- 这道题目 ...
- BZOJ2001 HNOI2010城市建设(线段树分治+LCT)
一个很显然的思路是把边按时间段拆开线段树分治一下,用lct维护MST.理论上复杂度是O((M+Q)logNlogQ),实际常数爆炸T成狗.正解写不动了. #include<iostream> ...
- P3206 [HNOI2010]城市建设 [线段树分治+LCT维护动态MST]
Problem 这题呢 就边权会在某一时刻变掉-众所周知LCT不支持删边的qwq- 所以考虑线段树分治- 直接码一发 如果 R+1 这个时间修改 那就当做 [L,R] 插入了一条边- 然后删的边和加的 ...
- BZOJ2001 HNOI2010 城市建设
题目大意:动态最小生成树,可以离线,每次修改后回答,点数20000,边和修改都是50000. 顾昱洲是真的神:顾昱洲_浅谈一类分治算法 链接: https://pan.baidu.com/s/1c2l ...
- [HNOI2010] 城市建设_动态最小生成树(Dynamic_MST)
这个题...暴力单次修改\(O(n)\),爆炸... $ $ 不过好在可以离线做 如果可以在 分治询问 的时候把图缩小的话就可以做了 硬着头皮把这个骚东西看完了 $ $ 动态最小生成树 然后,就把它当 ...
随机推荐
- Swift 里 Set(二)概览
类图  Set 是一个结构体,持有另一个结构体_Variant. 最终所有的元素存储在一个叫做__RawSetStorage的类里. 内存布局  结构体分配在栈上,和__RawSetStorage ...
- Alpha冲刺(3/10)——追光的人
1.队友信息 队员学号 队员博客 221600219 小墨 https://www.cnblogs.com/hengyumo/ 221600240 真·大能猫 https://www.cnblogs. ...
- FireFox浏览器-xpath快速定位插件:Xpath Checker
FireFox浏览器-xpath快速定位插件:Xpath Checker 插件截图:
- PHP:使用Zend对源码加密、Zend Guard安装以及Zend Guard Run-time support missing的解决方法
Zend Guard是目前市面上最成熟的PHP源码加密产品了.刚好需要对自己的产品进行加密,折腾了一晚上,终于搞定,将碰到的问题及解决方法记录下来,方便日后需要,也可以帮助其他人.我使用的是Wamps ...
- linux free命令详解(一)
一. 作用 free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区. 二. 语法 free [选项] 三. 选项 默认情况下,即在没有选项的情况下,&qu ...
- android app性能优化大汇总(google官方Android性能优化典范 - 第3季)
(1)Fun with ArrayMaps 程序内存的管理是否合理高效对应用的性能有着很大的影响,有的时候对容器的使用不当也会导致内存管理效率低下.Android为移动操作系统特意编写了一些更加高效的 ...
- Android H5调起原生微信或支付宝支付
Android H5调起原生微信或支付宝支付 WebView调用原生微信或支付宝回调:其原理就是在shouldOverrideUrlLoading(final WebView view, String ...
- salesforce 零基础学习(七十)使用jquery tree实现树形结构模式
项目中UI需要用到树形结构显示内容,后来尽管不需要做了,不过还是自己做着玩玩,mark一下,免得以后项目中用到. 实现树形结构在此使用的是jquery的dynatree.js.关于dynatree的使 ...
- 百度2015校园招聘面试题回忆录(成功拿到offer)
引言 盼望着,盼望着……今年终于轮到我找工作了,还深深记得去年跟在师兄后面各种打酱油的经历,当时觉得找工作好难啊,怎么面一个败一个,以后还能找到工作不? 不过当时的失败也是理所当然的,那时候没有做任何 ...
- solr(四) : springboot 整合 solr
前言: solr服务器搭起来, 数据导入之后, 就该应用到项目中去了. 那在项目中, 该怎么整合和应用solr呢? 接下来, 就来整合和应用solr 一. 整合 1. 引入jar包 <prope ...