【bzoj 4046 加强版】Pork barrel
刚考完以为是神仙题……后来发现好像挺蠢的…… 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的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- Bzoj3930: [CQOI 2015] 选数 & COGS2699: [CQOI 2015] 选数加强版
题面 Bzoj COGS加强版 Sol 非加强版可以枚举AC这里不再讲述 设\(f(i)\)表示在\([L, H]\)取\(N\)个,\(gcd为i\)的方案数 \(F(i)=\sum_{i|d}f( ...
- BZOJ.3673/3674.可持久化并查集(可持久化线段树 按秩合并/启发式合并)
BZOJ 3673 BZOJ 3674(加强版) 如果每次操作最多只修改一个点的fa[],那么我们可以借助可持久化线段树来O(logn)做到.如果不考虑找fa[]的过程,时空复杂度都是O(logn). ...
- 洛谷 P2056 BZOJ 2743 [HEOI2012]采花
//表示真的更喜欢洛谷的题面 题目描述 萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 ...
- CERC 2014 (动态树+主席树)
CERC 2014 Pork barrel Problem : n个点m条边有边权的无向图,有q个询问,每次询问权值在[L,R]内的边组成的最小生成树的权值和,强制在线. n <= 1000, ...
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 635 Solved: 177[Submit][Stat ...
- bzoj 2594: [Wc2006]水管局长数据加强版 动态树
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 934 Solved: 291[Submit][Sta ...
- BZOJ 3674 可持久化并查集加强版(路径压缩版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
- BZOJ 3674 可持久化并查集加强版(按秩合并版本)
/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持 ...
随机推荐
- SQL Server 等待统计信息基线收集
背景 我们随时监控每个服务器不同时间段的wait statistics ,可以根据监控信息大概判断什么时候开始出现异常,相当于一个wait statistics基线收集,还可以具体分析占比高的等待类型 ...
- 【AMAD】Stream-Framework -- 让你可以使用Cassandra和Redis构建新闻feed,活动流(activity stream)以及通知系统。
动机 简介 个人评分 动机 你曾经是否想为你自己的网站构建Facebook,Github那种feed流. 简介 通过Stream-Framework1你可以做到: Github那种活动流 Twitte ...
- logistics二分类
binaryclassification #DATASET: https://archive.ics.uci.edu/ml/datasets/Glass+Identificationimport nu ...
- Oracle 自增序列的生成
1.代码结构 .创建 第一种 -- Create sequence create sequence SEQ_USERID minvalue maxvalue start increment nocac ...
- 再谈js对象数据结构底层实现原理-object array map set
如果有java基础的同学,可以回顾下<再谈Java数据结构—分析底层实现与应用注意事项>:java把内存分两种:一种是栈内存,另一种是堆内存.基本类型(即int,short,long,by ...
- luoguP1379-八数码难题(双向bfs)
题目链接:https://www.luogu.org/problemnew/show/P1379 题意:用字符串表示八数码,求根据给定八数码得到末状态“123804765”最少的步数. 思路:这题很方 ...
- 大型软件公司.Net面试常见题(含答案)
1.a=10,b=15,在不用第三方变量的前提下,吧a.b互换 2.已知数组int[] max={6,5,2,9,7,4,0};用快速排序算法按降序对其进行排列,并返回数组 3.请简述面向对象的多态的 ...
- MySQL Explain命令详解--表的读取顺序,数据读取操作的类型等
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的) 不损失精确 ...
- springboot笔记-使用JSP
Spring Boot 项目中使用 JSP: 项目结构:需要添加webapp文件夹用来存放目录 jsp 文件 spring-boot-jsp +-src +- main +- java +- reso ...
- 区间最值的优秀数据结构---ST表
ST表,听起来高大上,实际上限制非常多,仅仅可以求最值问题: 为什么?先从原理看起: st表运用了倍增的思想:st[i][j] = min(st[i][j - 1],st[i + 2^(j - 1)) ...