刚考完以为是神仙题……后来发现好像挺蠢的…… QwQ

题意

  给你一张 \(n\) 个点 \(m\) 条边的无向图(不一定连通),有 \(q\) 组询问,每组询问给你 \(2\) 个正整数 \(l,h\),你需要选出一些边,满足边权都在 \([l,h]\) 范围内,连通尽量多的点对,在此基础上使得边权和最小。

  \(1\le n,m,q\le 10^5,\space 1\le w_i,l,h\le 10^4\)(原题 \(n\le 1000,\space q\le 10^6\))

题解

  动态最小生成树(汗)

  我怎么什么都没写过

  考场上花 10 分钟写了 5 分 \(O(qn)\) 暴力就滚了

  假设这题可以离线,先将所有边按权值从大到小排序。

  依次判断每条边的两端点是否连通,若未连通则连上(这样连通的点对数必定增多),若连通则替换掉一条树上这两点之间的简单路径上 权值最大的一条边(\(\text{cut}\) 一下权值最大的那条边,\(\text{link}\) 一下这条边)。

  加边的同时动态处理询问。对于一组询问 \([L,R]\),若当前插入的边的权值是 \(\ge L\) 的最小值,则我们决定处理这组询问。此时最小生成(森林)上的所有边权都 \(\ge L\),我们直接扔掉所有权值 \(\gt R\) 的边,剩余的边的权值和就是答案。发现边权很小,所以可以用树状数组动态维护最小生成(森林)中的边权,第 \(i\) 位记录所有权值为 \(i\) 的边的权值和,单点修改,区间查询。

  考虑在线,我想这题时居然忘了加边和询问是分开的了……

  依然把边按权值从大到小排序,每加入一条边时,第 \(i\) 个版本继承第 \(i+1\) 个版本,在主席树的第 \(w_i\) 个版本上单点修改即可。在线处理询问 \([L,R]\) 时在主席树的第 \(L\) 个版本上区间查询即可。

  复杂度 \(O(n\log n)\)。

  仔细想想好像确实挺水的,所以还是我太菜了

  附注:

  1. \(LCT\) 一般维护点权,边权不太好维护,可以把第 \(i\) 条边转成一个编号为 \(i+n\) 的点,然后加入这条边的时候 把这个点与边的两端点 \(\text{link}\) 一下即可

  2. 注意主席树的空间是 \(O(2m\log w)\) 的!!!不是 \(O(10000\log 10000)\)!!!因为这个 sb 问题调了一小时 zbl

#include<bits/stdc++.h>
#define N 200010
using namespace std;
inline int read(){
int x=0; bool f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
if(f) return x; return 0-x;
}
int n,m,online,q;
struct inp{int u,v,w;}a[N<<1];
inline bool cmp(inp a, inp b){
return a.w>b.w;
}
namespace LCT{
#define son(x,fx) tr[x].son[fx]
struct Tree{int fa,son[2],v,mx_id; bool r;}tr[N<<1];
inline bool isRoot(int x){
return son(tr[x].fa,0)!=x && son(tr[x].fa,1)!=x;
}
inline bool idf(int x){
return son(tr[x].fa,1)==x;
}
void pushup(int x){
tr[x].mx_id=x;
if(tr[tr[son(x,0)].mx_id].v > tr[tr[x].mx_id].v) tr[x].mx_id=tr[son(x,0)].mx_id;
if(tr[tr[son(x,1)].mx_id].v > tr[tr[x].mx_id].v) tr[x].mx_id=tr[son(x,1)].mx_id;
}
void pushdown(int x){
if(tr[x].r){
swap(son(x,0),son(x,1));
tr[son(x,0)].r^=1, tr[son(x,1)].r^=1;
tr[x].r=0;
}
}
void pd(int x){
if(!isRoot(x)) pd(tr[x].fa);
pushdown(x);
}
inline void connect(int x, int f, int fx){
tr[x].fa=f, son(f,fx)=x;
}
void rotate(int x){
int y=tr[x].fa, z=tr[y].fa, idf_x=idf(x), idf_y=idf(y), B=son(x,idf_x^1);
if(!isRoot(y)) connect(x,z,idf_y);
else tr[x].fa=z;
connect(B,y,idf_x), connect(y,x,idf_x^1);
pushup(y), pushup(x);
}
void splay(int x){
pd(x);
int f;
for(; !isRoot(x); ){
f=tr[x].fa;
if(!isRoot(f)) rotate(idf(x)==idf(f) ? f : x);
rotate(x);
}
}
void access(int x){
for(int y=0; x; x=tr[y=x].fa){
splay(x);
son(x,1)=y;
pushup(x);
}
}
void makeroot(int x){
access(x), splay(x), tr[x].r^=1;
}
void link(int x, int y){
makeroot(x);
tr[x].fa=y;
}
int cutMax(int x, int y){
makeroot(x);
access(y);
splay(y);
x=tr[y].mx_id;
splay(x);
tr[son(x,0)].fa=tr[son(x,1)].fa=0;
son(x,0)=son(x,1)=0;
return x;
}
#undef son
}using namespace LCT;
namespace PT{
#define son(x,fx) tr[o].son[fx]
int cnt,rt[100010];
struct Tree{int son[2],sum;}tr[200010*20];
void ins(int &o, int pre, int l, int r, int x, int v){
tr[o=++cnt] = tr[pre], tr[o].sum += v;
if(l==r) return;
int mid=l+r>>1;
if(x<=mid) ins(son(o,0),son(pre,0),l,mid,x,v);
else ins(son(o,1),son(pre,1),mid+1,r,x,v);
}
int query(int o, int l, int r, int L, int R){
if(!o) return 0;
if(L<=l && r<=R) return tr[o].sum;
int mid=l+r>>1, ret=0;
if(L<=mid) ret+=query(son(o,0),l,mid,L,R);
if(R>mid) ret+=query(son(o,1),mid+1,r,L,R);
return ret;
}
}using namespace PT;
namespace DSU{
int fa[N];
void init(){
for(int i=1; i<=n; ++i) fa[i]=i;
}
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
}using namespace DSU;
int main(){
n=read(), m=read(), online=read();
for(int i=1; i<=m; ++i) a[i].u=read(), a[i].v=read(), a[i].w=read();
sort(a+1,a+m+1,cmp);
init();
int fu,fv;
for(int i=1; i<=m; ++i){
rt[a[i].w]=rt[a[i-1].w];
fu=find(a[i].u), fv=find(a[i].v);
if(fu==fv){
q=cutMax(a[i].u,a[i].v);
ins(rt[a[i].w],rt[a[i].w],1,a[1].w,LCT::tr[q].v,-LCT::tr[q].v);
}
else{
DSU::fa[fv]=fu;
q=n+i;
}
LCT::tr[q].v=a[i].w;
LCT::tr[q].mx_id=q;
link(a[i].u,q), link(q,a[i].v);
ins(rt[a[i].w],rt[a[i].w],1,a[1].w,a[i].w,a[i].w);
}
for(int i=a[1].w-1; i>0; --i)
if(rt[i]==0) rt[i]=rt[i+1]; q=read();
int l,r,lastans=0;
while(q--){
l=read()-online*lastans, r=read()-online*lastans;
printf("%d\n",lastans=query(rt[l],1,a[1].w,1,r));
}
return 0;
}
/*
5 7 1
1 2 2
2 3 4
3 4 3
4 5 1
5 1 3
2 5 4
1 4 5
5
1 2
4 7
11 12
11 13
18 19
*/

【bzoj 4046 加强版】Pork barrel的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. Bzoj3930: [CQOI 2015] 选数 & COGS2699: [CQOI 2015] 选数加强版

    题面 Bzoj COGS加强版 Sol 非加强版可以枚举AC这里不再讲述 设\(f(i)\)表示在\([L, H]\)取\(N\)个,\(gcd为i\)的方案数 \(F(i)=\sum_{i|d}f( ...

  3. BZOJ.3673/3674.可持久化并查集(可持久化线段树 按秩合并/启发式合并)

    BZOJ 3673 BZOJ 3674(加强版) 如果每次操作最多只修改一个点的fa[],那么我们可以借助可持久化线段树来O(logn)做到.如果不考虑找fa[]的过程,时空复杂度都是O(logn). ...

  4. 洛谷 P2056 BZOJ 2743 [HEOI2012]采花

    //表示真的更喜欢洛谷的题面 题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 ...

  5. CERC 2014 (动态树+主席树)

    CERC 2014 Pork barrel Problem : n个点m条边有边权的无向图,有q个询问,每次询问权值在[L,R]内的边组成的最小生成树的权值和,强制在线. n <= 1000, ...

  6. bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 177[Submit][Stat ...

  7. bzoj 2594: [Wc2006]水管局长数据加强版 动态树

    2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec  Memory Limit: 128 MBSubmit: 934  Solved: 291[Submit][Sta ...

  8. BZOJ 3674 可持久化并查集加强版(路径压缩版本)

    /* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...

  9. BZOJ 3674 可持久化并查集加强版(按秩合并版本)

    /* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...

随机推荐

  1. Redis 高级应用

    Redis SAVE 命令用于创建当前数据库的备份 该命令将在 redis 安装目录中创建dump.rdb文件. 如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并 ...

  2. IDEA的version control log为空,该怎么办?

    问题描述: 解决方案: 关掉IDEA,重新打开,即可药到病除

  3. [笔记] 使用frp从外网访问内网

    之前尝试过otunnel,也记录过使用方法,见[笔记] 使用otunnel从外网访问内网,但是用了几天发现还是不够稳定. 然后尝试frp,发现性能稳定,够用,将过程及配置分享在这里吧. 需求 内网机器 ...

  4. 2019 1月 第三次java基础有感

    毕业半年了,一直在游戏公司做游戏服务器开发,java语言. 工作中,写着写着代码,接触java多了,有时候就会发现自己的java基础会不够用.以前实习的时候也体会到一次,然后过了一遍基础.现在正式工作 ...

  5. golang struct结构体初始化的几种方式

    type User struct { Id int `json:"id" orm:"auto"` // 用户名 Username string `json:&q ...

  6. 【MapReduce】二、MapReduce编程模型

      通过前面的实例,可以基本了解MapReduce对于少量输入数据是如何工作的,但是MapReduce主要用于面向大规模数据集的并行计算.所以,还需要重点了解MapReduce的并行编程模型和运行机制 ...

  7. U盘安装Ubuntu Server CD-ROM挂载失败

    U盘安装 Ubuntu Server 发生Failed to copy file from CD-ROM问题 使用UltraISO制作Ubuntu Server安装盘,在安装过程中出现[!!] Loa ...

  8. 【Linux开发】linux设备驱动归纳总结(三):3.设备驱动面向对象思想和lseek的实现

    linux设备驱动归纳总结(三):3.设备驱动面向对象思想和lseek的实现 一.结构体struct file和struct inode 在之前写的函数,全部是定义了一些零散的全局变量.有没有办法整合 ...

  9. 开启httpfs

    参考: https://docs.cloudera.com/documentation/enterprise/6/6.2/topics/admin_httpfs.html#xd_583c10bfdbd ...

  10. Redis 以及 Python操作Redis

    Redis Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis有以下特点: -- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可 ...