一棵有根树,每个点有一个音高,有 $m$ 中弹奏方法,每种方法可以弹奏 $d$ 子树中音高在 $[l,r]$ 间的音符,每种方法最多弹 $t$ 次

求最多能弹出多少个音符

$n \leq 10000$

sol:

网络流

暴力连边是

1. $S \rightarrow 每个点$

2. $每个方法 \rightarrow T$

3. $每个点 \rightarrow 每个能用到的方法$

第一种边限制是 $1$ ,第二种边限制是 $t$,第三种边没有限制

第一第二种不好优化,考虑优化第三种

第三种本质上是对树上 $dfn$ 是一段区间(子树),权值也是一段区间的点连边

考虑数据结构优化

可以使用可持久化线段树合并

一开始每个点向它所在的线段树上的点连边

每次合并的时候原来的点向合并出来的新点连边

对于方法我们把它能作用的区域向它连边

这样边数是 $O(2n) + O(可持久化线段树)$ 的,大概是 $O(nlogn)$

#include <bits/stdc++.h>
#define LL long long
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {
int x = , f = ; char ch;
for (ch = getchar(); !isdigit(ch); ch = getchar()) if (ch == '-') f = -f;
for (; isdigit(ch); ch = getchar()) x = * x + ch - '';
return x * f;
}
const int maxn = , maxm = , inf = ;
struct Dinic {
int cur[maxm], head[maxm], nx[maxm];
int n, m, s, t;
struct Edge {
int from, to, caps;
Edge(){}
Edge(int _1, int _2, int _3): from(_1), to(_2), caps(_3) {}
}es[maxm];
void AddEdge(int u, int v, int w) {
es[m] = Edge(u, v, w); nx[m] = head[u]; head[u] = m++;
es[m] = Edge(v, u, ); nx[m] = head[v]; head[v] = m++;
}
void setn(int _) {n = _;}
Dinic() {m = ; memset(head, -, sizeof(head));}
queue<int> q; int dis[maxn];
bool BFS() {
rep(i, , n) dis[i] = ;
q.push(t); dis[t] = ;
while(!q.empty()) {
int now = q.front(); q.pop();
for(int i=head[now];~i;i=nx[i]) {
Edge &e = es[i^];
if(!dis[e.from] && e.caps) {
dis[e.from] = dis[now] + ;
q.push(e.from);
}
}
}
return (dis[s] > );
}
int DFS(int u, int a) {
if(u == t || !a) return a;
int flow = , f;
for(int &i = cur[u]; ~i; i = nx[i]) {
Edge &e = es[i];
if(dis[e.to] == dis[u] - && (f = DFS(e.to, min(e.caps, a)))) {
e.caps -= f; es[i^].caps += f;
a -= f; flow += f;
if(!a) return flow;
}
}
return flow;
}
int MaxFlow(int _s, int _t) {
s = _s, t = _t; int res = ;
while(BFS()) {
memcpy(cur, head, (n + ) * sizeof(int));
res += DFS(s, );
}
return res;
}
} sol;
int s, t, nodes;
struct Ques {
int l, r, d, t;
Ques(){}
Ques(int _1, int _2, int _3, int _4) : l(_1), r(_2), d(_3), t(_4) {}
}qs[maxn];
int n, m;
int fa[maxn], h[maxn];
int first[maxn], nx[maxn], to[maxn], cnt;
inline void add(int u, int v) {
to[++cnt] = v;
nx[cnt] = first[u];
first[u] = cnt;
}
int root[maxn], ls[maxm << ], rs[maxm << ], dfn;
inline void Insert(int &x, int l, int r, int pos, int p) {
x = ++dfn;
if(l == r) {
sol.AddEdge(p, x + nodes, inf);
return;
}
int mid = (l + r) >> ;
if(pos <= mid) Insert(ls[x], l, mid, pos, p) ;
else Insert(rs[x], mid + , r, pos, p) ;
if(ls[x]) sol.AddEdge(ls[x] + nodes, x + nodes, inf);
if(rs[x]) sol.AddEdge(rs[x] + nodes, x + nodes, inf);
}
inline int merge(int x, int y, int l, int r) {
if(!x || !y) return x + y;
int z = ++dfn;
if(l == r) {
sol.AddEdge(x + nodes, z + nodes, inf);
sol.AddEdge(y + nodes, z + nodes, inf);
return z;
}
int mid = (l + r) >> ;
ls[z] = merge(ls[x], ls[y], l, mid);
rs[z] = merge(rs[x], rs[y], mid+, r);
if(ls[z]) sol.AddEdge(ls[z] + nodes, z + nodes, inf);
if(rs[z]) sol.AddEdge(rs[z] + nodes, z + nodes, inf);
return z;
}
inline void link(int x, int l, int r, int L, int R, int p) {
if(!x) return;
if(L <= l && r <= R) {
sol.AddEdge(x + nodes, p, inf);
return;
}
int mid = (l + r) >> ;
if(L <= mid) link(ls[x], l, mid, L, R, p);
if(R > mid) link(rs[x], mid+, r, L, R, p);
}
inline void dfs(int x) {
Insert(root[x], , n, h[x], x);
for(int i=first[x];i;i=nx[i]) {
dfs(to[i]);
root[x] = merge(root[x], root[to[i]], , n);
}
} int main() {
n = read(), m = read();
s = n + m + , t = n + m + , nodes = t + ;
rep(i, , n) {
fa[i] = read();
add(fa[i], i);
}
rep(i, , n) {
h[i] = read();
sol.AddEdge(s, i, );
} dfs();
rep(i, , m) {
int l = read(), r = read(), d = read(), ct = read();
link(root[d], , n, l, r, i+n);
qs[i] = Ques(l, r, d, ct); sol.AddEdge(i + n, t, ct);
}
sol.setn(nodes + dfn + );
cout << sol.MaxFlow(s, t) << endl;
}

bzoj 3681 Arietta的更多相关文章

  1. 【BZOJ 3681】Arietta

    传送门 题目描述 Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中. 但是她从未停止过和恋人 Velding 的书信往来.一天,她准备去探访他. 对着窗外的阳光,临 ...

  2. [BZOJ 3681]Ariettad

    终于是打完了 CH 上的数据结构专场了…… 不过看样子还有一套 5555 传送门: http://ch.ezoj.tk/contest/CH%20Round%20%2351%20-%20Shinrei ...

  3. BZOJ 3681 线段树合并+网络流

    思路: 暴力建图有n*m条边 考虑怎么优化 (那就只能加个线段树了呗) 然后我就不会写了..... 抄了一波题解 //By SiriusRen #include <bits/stdc++.h&g ...

  4. BZOJ3681: Arietta

    题解: 数据结构来优化网络流,貌似都是用一段区间来表示一个点,然后各种乱搞... 发现主席树好吊...在树上建主席树貌似有三种方法: 1.建每个点到根节点这条链上的主席树,可以回答和两点间的路径的XX ...

  5. 【BZOJ-3681】Arietta 网络流 + 线段树合并

    3681: Arietta Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 182  Solved: 70[Submit][Status][Discuss ...

  6. bzoj AC倒序

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

  7. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  8. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  9. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

随机推荐

  1. 统计easyui datagrid某列之和显示在对应列下面

    项目需求要在表格下面加一行统计求和的,结果网上搜寻了一堆,要么说的不详细,高深大牛们的见解:要么实现不了,搜寻老半天修改出一个可以用的,做一下学习记录,新手菜鸟,欢迎指正和新解决方案. 最终效果图: ...

  2. Python基础知识补充(重要)-作用域、特殊语法

    Python作用域 python代码内部块如if语句内声明变量,在if代码段后在调用此变量并未报如“undefinded name"此类错误,例子如下: if 1 == 1: name = ...

  3. arcgis flex aqi 3大util

    第一:webMapUtil 主要用来根据id或者json创建map,跟webmap相关 第二:GeometryUtil 主要用来计算面积,长度,还有判断是否相交等,跟geometry相关. 第三:We ...

  4. 生成sql表结构

    DataConstruct.php <?php /** * Created by PhpStorm. * User: Administrator * Date: 2017/7/21 * Time ...

  5. Linux基础三---打包压缩&vim&系统的初始化和服务

    一,常用命令——tar&vim 1. tar [参数]  文件名  [路径] 参数: -c :建立一个压缩文件的参数指令(create 的意思):     -x :解开一个压缩文件的参数指令! ...

  6. 跨平台移动开发 Xuijs超轻量级的框架Style CSS属性用法

    PhoneGap里面推荐使用的超轻量级的框架 Style CSS属性用法 设置css属性:setstyle 通过ID设置css属性 x$('#top1').setStyle('color', '#DB ...

  7. LVS 负载均衡原理详解

    LVS简介 LVS是一个开源软件,由章文嵩博士于1998年5月创立,可以实现Linux平台下的简单负载均衡.LVS是Linux Virtual Server的简写,是一个虚拟的服务器集群系统. LVS ...

  8. mongodb的原子性(Atomicity)和事物 (Transactions)

    在mongodb中,单个的写操作保持原子性是在单个的document 上. $isolated operator $isolated 一个写操作多个documents 的时候可以防止和其他进程交织,一 ...

  9. 使用iframe,注销以后,点击某个标签,跳转到的登录页面位于标签中

    当使用iframe时,要么会话过期,要么手动注销,如果此时再进行操作,可能遇到跳转到登录页面,可是登录页面会位于标签执行,并没有全屏显示,即位于当前的iframe中,此时的解决方式很简单,只需要在登录 ...

  10. 安装mysql5.7后无法启动,/var/run/mysqld 目录每次重启后都需要手动去创建--终极解决方案

    鉴于很多童鞋反应,mysql5.7安装后出现无法启动,建立/var/run/mysqld 并赋权mysql用户解决了启动的问题,但是重启系统后又出现无法启动的问题,导致/var/run/mysqld ...