这个题。。。暴力单次修改\(O(n)\),爆炸。。。
$
$
不过好在可以离线做
如果可以在 分治询问 的时候把图缩小的话就可以做了
硬着头皮把这个骚东西看完了
$
$
动态最小生成树
然后,就把它当板子写好了。。。
思路是这样的:
经过修改后会得到 \(K\) 个 \(MST\),在这些 \(MST\) 中,有些边是反复在用的,有些边是一直没有用到的
那么考虑把这些边去除掉,就能把图给缩小
关键就是这么两个东西:

  1. \(contraction\)
    处理必需边,将询问中的边权值设为 \(-inf\) ,做一遍 \(MST\) ,这时 \(MST\) 中的 非\(-inf\) 的边就是必需边
    把这些边两端的点缩起来(可以用并查集维护),顺便统计一下边权和,再将其他边连回来

  2. \(reduction\)
    处理无用边将询问中的边权值设为inf,做 \(MST\) ,不在 \(MST\) 中的 非\(inf\) 的边就是无用边,可以直接删除

图片蒯自 顾昱洲_浅谈一类分治算法
$
$
这样子的话在每一层都可以去掉一些点和一些边,就能在分治询问的时候缩小图的规模
总结一下的话,大致流程就是这个样子的:

  1. 当前递归区间 \([l,r]\);
  2. 若 \(l=r\) ,暴力修改,统计答案并 \(return\);
  3. \(contraction\),\(reduction\);
  4. 递归 \([l,mid]\) , \([mid+1,r]\);

$
$

//made by Hero_of_Someone
//哎呀这个代码...懒得写归并了,排序都用 sort 凑合一下算了...
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define N (100010)
#define ll long long
#define inf 1ll<<54
#define RG register
using namespace std;
inline int gi(){ RG int x=0,q=1; RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  if(ch=='-') q=-1,ch=getchar(); while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=getchar(); return q*x; }
void File(){freopen(".in","r",stdin);freopen(".out","w",stdout);}

ll Ans[N];
int n,m,q;
int a[N],sum[54],pos[N];
struct ques{ int k,d; }que[N];
struct Edge{ int u,v,id; ll w;
  inline bool operator<(const Edge& a)const{ return w<a.w; }
}e[54][N],tmp[N],t[N];

int fa[N];
inline int find(RG int x){ return fa[x]==x?x:fa[x]=find(fa[x]); }

inline void init(){
  n=gi(),m=gi(),q=gi();
  for(RG int i=1;i<=m;i++){
    e[0][i].u=gi(),e[0][i].v=gi();
    a[i]=e[0][i].w=gi();
    e[0][i].id=i;
  }
  sum[0]=m;
  for(RG int i=1;i<=q;i++)
    que[i].k=gi(),que[i].d=gi();
}

inline void clear(int x){
  for(RG int i=1;i<=x;i++){
    fa[tmp[i].u]=tmp[i].u;
    fa[tmp[i].v]=tmp[i].v;
  }
}

inline void contraction(int& cnt,ll& ret){  //处理必需边
  RG int num=0;
  sort(tmp+1,tmp+cnt+1); clear(cnt);
  for(RG int i=1;i<=cnt;i++){
    RG int fx=find(tmp[i].u),fy=find(tmp[i].v);
    if(fx==fy) continue;
    fa[fx]=fy; t[++num]=tmp[i];
  }
  for(RG int i=1;i<=num;i++){
    fa[t[i].u]=t[i].u;
    fa[t[i].v]=t[i].v;
  }
  for(RG int i=1;i<=num;i++){  //将必需边两端缩起来
    if(t[i].w==-inf) continue;
    RG int fx=find(t[i].u),fy=find(t[i].v);
    ret+=t[i].w,fa[fx]=fy;
  }
  num=0;
  for(RG int i=1;i<=cnt;i++){  //缩点后的新图重新连边
    RG int fx=find(tmp[i].u),fy=find(tmp[i].v);
    if(fx==fy) continue;
    t[++num]=tmp[i];
    t[num].u=fx,t[num].v=fy;
    pos[tmp[i].id]=num;
  } cnt=num;
  for(RG int i=1;i<=cnt;i++) tmp[i]=t[i];
}

inline void reduction(int& cnt){  //处理无用边
  sort(tmp+1,tmp+cnt+1);
  RG int num=0; clear(cnt);
  for(RG int i=1;i<=cnt;i++){  //只留下当前MST中的边
    RG int fx=find(tmp[i].u),fy=find(tmp[i].v);
    if(fx==fy){ //待修改边也要留下
      if(tmp[i].w==inf){
    t[++num]=tmp[i];
    pos[tmp[i].id]=num;
      }
      continue;
    }
    fa[fx]=fy;
    t[++num]=tmp[i];
    pos[tmp[i].id]=num;
  } cnt=num;
  for(RG int i=1;i<=cnt;i++) tmp[i]=t[i];
}

inline void Solve(int l,int r,int dep,ll ret){
  RG int cnt=sum[dep];
  if(l==r) a[ que[l].k ]=que[l].d;
  for(RG int i=1;i<=cnt;i++){
    e[dep][i].w=a[ e[dep][i].id ];
    pos[ e[dep][i].id ]=i;
    tmp[i]=e[dep][i];
  }
  if(l==r){
    clear(cnt);
    sort(tmp+1,tmp+cnt+1);
    for(RG int i=1;i<=cnt;i++){
      RG int fx=find(tmp[i].u),fy=find(tmp[i].v);
      if(fx==fy) continue;
      fa[fx]=fy; ret+=tmp[i].w;
    }
    Ans[l]=ret;
    return ;
  }
  RG int mid=(l+r)>>1;
  for(RG int i=l;i<=r;i++) tmp[ pos[que[i].k] ].w=-inf;
  contraction(cnt,ret);
  for(RG int i=l;i<=r;i++) tmp[ pos[que[i].k] ].w=inf;
  reduction(cnt); sum[dep+1]=cnt;
  for(RG int i=1;i<=cnt;i++) e[dep+1][i]=tmp[i];
  Solve(l,mid,dep+1,ret); Solve(mid+1,r,dep+1,ret);
}

inline void work(){
  Solve(1,q,0,0);
  for(RG int i=1;i<=q;i++)
    printf("%lld\n",Ans[i]);
}

int main(){ init(); work(); return 0; }

[HNOI2010] 城市建设_动态最小生成树(Dynamic_MST)的更多相关文章

  1. [HNOI2010]城市建设

    [HNOI2010]城市建设 玄学cdq O(nlog^2n)的动态最小生成树 其实就是按照时间cdq分治+剪枝(剪掉一定出现和不可能出现的边) 处理[l,r]之间的修改以及修改之后的询问,不能确定是 ...

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

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

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

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

  4. BZOJ2001 HNOI2010 城市建设

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

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

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

  6. Luogu 3206 [HNOI2010]城市建设

    BZOJ 2001 很神仙的cdq分治 先放论文的链接   顾昱洲_浅谈一类分治算法 我们考虑分治询问,用$solve(l, r)$表示询问编号在$[l, r]$时的情况,那么当$l == r$的时候 ...

  7. Uoj #274. 【清华集训2016】温暖会指引我们前行 LCT维护边权_动态最小生成树

    Code: 行#include<bits/stdc++.h> #define ll long long #define maxn 1000000 #define inf 100000000 ...

  8. 洛谷P3206 [HNOI2010]城市建设

    神仙题 题目大意: 有一张\(n\)个点\(m\)条边的无向联通图,每次修改一条边的边权,问每次修改之后这张图的最小生成树权值和 话说是不是\(cdq\)题目都可以用什么数据结构莽过去啊-- 这道题目 ...

  9. BZOJ2001 HNOI2010城市建设(线段树分治+LCT)

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

随机推荐

  1. 使用yield返回IEnumber<T>集合

    yield是对一种复杂行为的简化,就是将一段代码简化为一种简单的形式. 先看一下常规的写法,下面例子中,把找出字符串阵列中,某些元素包含有某些字符的元素. class Bi { public stri ...

  2. c#对联合体的封装

    https://blog.csdn.net/u012846041/article/details/37518313 标准C或者C++中均提供关键字定义联合结构,C#中未提供类似的关键字,但仍然可以定义 ...

  3. PowerBI开发 第十五篇:DAX 表达式(时间+过滤+关系)

    DAX表达式中包含时间关系(Time Intelligence)相关的函数,用于对日期维度进行累加.同比和环比等分析.PowerBI能够创建关系,通过过滤器来对影响计算的上下文. 一,时间关系 DAX ...

  4. 闭包----你所不知道的JavaScript系列(4)

    一.闭包是什么? · 闭包就是可以使得函数外部的对象能够获取函数内部的信息. · 闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. · 闭包就 ...

  5. CSS 列表实例

    CSS 列表属性允许你放置.改变列表项标志,或者将图像作为列表项标志.CSS 列表属性(list)属性 描述list-style 简写属性.用于把所有用于列表的属性设置于一个声明中.list-styl ...

  6. nginx域名访问的白名单配置梳理

    在日常运维工作中,会碰到这样的需求:设置网站访问只对某些ip开放,其他ip的客户端都不能访问.可以通过下面四种方法来达到这种效果:1)针对nginx域名配置所启用的端口(比如80端口)在iptable ...

  7. Centos下内网DNS主从环境部署记录

    一.DNS是什么?DNS(Domain Name System),即域名系统.它使用层次结构的命名系统,将域名和IP地址相互映射,形成一个分布式数据库系统. DNS采用C-S架构,服务器端工作在UDP ...

  8. HTTP协议冷知识大全

    如果不用HTTPS,HTTP协议如何安全的传输密码信息? HTTP协议是纯文本协议,没有任何加密措施.通过HTTP协议传输的数据都可以在网络上被完全监听.如果用户登陆时将用户名和密码直接明文通过HTT ...

  9. Python-dict-12

    字典 Why:咱们目前已经学习到的容器型数据类型只有list,那么list够用?他有什么缺点呢? 1. 列表可以存储大量的数据类型,但是如果数据量大的话,他的查询速度比较慢. 2. 列表只能按照顺序存 ...

  10. vue 动态修改 css

    <div v-for="i in resultDate" v-if="i.ProjectId>='4'" @click=EveyTesttInfo( ...