刚考完以为是神仙题……后来发现好像挺蠢的…… 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. linux常用命令(20)用SecureCRT来上传和下载文件

    用SSH管理linux服务器时经常需要远程与本地之间交互文件.而直接用SecureCRT自带的上传下载功能无疑是最方便的,SecureCRT下的文件传输协议有ASCII.Xmodem.Zmodem.  ...

  2. Django>ORM字段和参数

    Django之ORM字段和参数   字段 常用字段 AutoField 自增int自增列,必须填入参数 primary_key=True. 当model中如果没有自增列,则自动会创建一个列名为id的列 ...

  3. 页面Demo实现

    1.实现效果如下所示: 此Demo涉及到的知识点有: 1.页面布局思路; 2.TableViewCell实现单元格动态行高; 3.设置字符串中数字的颜色; 4.Cell圆角实现方法之一; 5.Cell ...

  4. java7:(Files.walkFileTree())

    1.Files.walkFileTree(): 顺序:顺序访问,碰到目录会一直递归下去 package com.test; import java.io.File; import java.io.IO ...

  5. app测试自动化之混合APP(之前的三篇为原生APP的操作)

    混合开发的App中,经常会有内嵌的H5页面:定位方法与原生APP不同,需要上下文切换 #获取所有上下文contexts=dr.contextsprint(contexts)#打印当前上下文(有点问题应 ...

  6. Python基础知识(程序结构)

    流程控制语句 选择语句.条件表达式.循环语句.跳转语句.pass空语句 程序结构三种基本结构 顺序结构.选择结构.循环结构 顺序结构 按照代码顺序依次运行 选择结构 根据条件表达式结果选择执行不同的语 ...

  7. 业务型代码常用的SQL汇总(随时更新)

    做了一年的业务代码开发,记录并分享一下自己平时在项目中遇到的比较好用的sql 1.查询表中是否某一字段下的数据有重复数据(以ID为例) SELECT id FROM 表名GROUP BY ID HAV ...

  8. MySQL 查看约束,添加约束,删除约束 添加列,修改列,删除列

    查看表的字段信息:desc 表名; 查看表的所有信息:show create table 表名; 添加主键约束:alter table 表名 add constraint 主键 (形如:PK_表名) ...

  9. Ubuntu 16.04安装anaconda3

    首先下载anaconda3镜像,清华大学开源软件镜像站下载地址:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 因为实验需要用到tenso ...

  10. CentOS下Vim加密解密文本

    CentOS用vim/vi给文件加密和解密 一. 利用 vim/vi 加密: 优点:加密后,如果不知道密码,就看不到明文,包括root用户也看不了: 缺点:很明显让别人知道加密了,容易让别人把加密的文 ...