【BZOJ 3681】Arietta
题目描述
Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中。
但是她从未停止过和恋人 Velding 的书信往来。一天,她准备去探访他。
对着窗外的阳光,临行前她再次弹起了琴。
她的琴的发声十分特殊。
让我们给一个形式化的定义吧。
所有的 n 个音符形成一棵由音符 C ( 1 号节点) 构成的有根树,每一个音符有一个音高 Hi 。
Arietta 有 m 个力度,第 i 个力度能弹出 Di 节点的子树中,音高在 [Li,Ri] 中的任意一个音符。
为了乐曲的和谐,Arietta 最多会弹奏第 i 个力度 Ti 次。
Arietta 想知道她最多能弹出多少个音符。
Sol
显然就是个最大权匹配问题,用网络流解决。
暴力连边边数显然爆炸,所以用个数据结构优化一下连边就可以了。
这里既然是子树那么自然就用线段树合并来维护就可以了。
每次合并的时候新建点并连边。然后叶子节点注意可能有多个点有相同的 H 所以应该新建点向原来的点各连一条边。
code:
#include<bits/stdc++.h>
using namespace std;
#define Set(a,b) memset(a,b,sizeof(a))
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}typedef long long ll;
const int N=1e4+10;
const int MAXN=4e5;
const int MAXM=1e6;
const int INF=1e9;
int H[N],rt[N],ls[MAXN],rs[MAXN];int n,m;
vector<int> Son[N];
int cur=0,S,T;
struct edge{
int to,next,cap;
}a[MAXM<<1];
int head[MAXN],cnt=0,d[MAXN];
inline void add(int x,int y,int z){a[cnt]=(edge){y,head[x],z};head[x]=cnt++;}
inline void add_edge(int x,int y,int z){add(x,y,z),add(y,x,0);}
inline void Insert(int&u,int l,int r,int i){
u=++cur;if(l==r) return add_edge(T+u,i,INF);
int mid=(l+r)>>1;
if(mid>=H[i]) Insert(ls[u],l,mid,i),add_edge(T+u,T+ls[u],INF);
else Insert(rs[u],mid+1,r,i),add_edge(T+u,T+rs[u],INF);
return;
}
void Link(int u,int l,int r,int L,int R,int p){
if(!u) return;
if(l>=L&&r<=R) return add_edge(p,T+u,INF);
int mid=(l+r)>>1;
if(mid>=L) Link(ls[u],l,mid,L,R,p);
if(mid< R) Link(rs[u],mid+1,r,L,R,p);
return;
}
int Merge(int u,int v,int l,int r) {
if(!u||!v) return u|v;int p=++cur;
if(l==r) {
add_edge(T+p,T+u,INF),add_edge(T+p,T+v,INF);
return p;
}int mid=(l+r)>>1;
ls[p]=Merge(ls[u],ls[v],l,mid);
rs[p]=Merge(rs[u],rs[v],mid+1,r);
if(ls[p]) add_edge(T+p,T+ls[p],INF);
if(rs[p]) add_edge(T+p,T+rs[p],INF);
return p;
}
void dfs(int u){
Insert(rt[u],1,n,u);
vector<int>::iterator iter;
for(iter=Son[u].begin();iter!=Son[u].end();++iter) {int v=*iter;dfs(v);rt[u]=Merge(rt[u],rt[v],1,n);}
return;
}
int TAIL,now[MAXN];
int dfs(int u,int flow){
if(u==T) return flow;
int res=flow;
for(int v,&i=now[u];~i;i=a[i].next) {
v=a[i].to;if(!a[i].cap||d[v]!=d[u]+1) continue;
int f=dfs(v,min(res,a[i].cap));
a[i].cap-=f,a[i^1].cap+=f,res-=f;
if(!f) d[v]=0;
if(!res) break;
}return flow-res;
}
queue<int> Q;
inline bool bfs(){
while(!Q.empty()) Q.pop();
for(int i=0;i<=TAIL;++i) d[i]=0;
d[S]=1;Q.push(S);
while(!Q.empty()) {
int u=Q.front();Q.pop();
for(int v,i=head[u];~i;i=a[i].next) {
v=a[i].to;if(!a[i].cap||d[v]) continue;
d[v]=d[u]+1;if(v==T) return 1;
Q.push(v);
}
}
return d[T];
}
inline int Dinic(){int flow=0;while(bfs()) {for(int i=S;i<=TAIL;++i) now[i]=head[i];flow+=dfs(S,INF);}return flow;}
int main()
{
freopen("data.in","r",stdin);
freopen("my.out","w",stdout);
init(n),init(m);int f;Set(head,-1);
for(int i=2;i<=n;++i) init(f),Son[f].push_back(i);
S=0,T=n+m+1;
for(int i=1;i<=n;++i) init(H[i]),add_edge(i,T,1);
dfs(1);
for(int i=1;i<=m;++i) {
int L,R,D,Ti;
init(L),init(R),init(D),init(Ti);
add_edge(S,i+n,Ti);Link(rt[D],1,n,L,R,i+n);
}TAIL=T+cur;printf("%d\n",Dinic());
return 0;
}
【BZOJ 3681】Arietta的更多相关文章
- 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)
1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...
- Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路
首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego
[bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...
- 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)
dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...
- 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3940 Solved: 1736 Description ...
- 【BZOJ 2132】圈地计划 && 【7.22Test】计划
两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...
- -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】
[把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...
- 【BZOJ 1032】 [JSOI2007]祖码Zuma
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1032 [题意] [题解] /* 设f[i][j]表示从第i个珠子开始的j个珠子被消除; ...
随机推荐
- 10 mysql选错索引
10 mysql选错索引 在mysql表中可以支持多个索引,有的sql不指定使用哪个索引,由mysql自己来决定,但是有时候mysql选错了索引,导致执行很慢. 例子 CREATE TABLE `t1 ...
- When specified, "proxy" in package.json must be a string.
react项目在package.json中配置proxy之后,报错 $ npm run start > img@ start D:\xx\src\img > react-scripts s ...
- 人工智能AI------有限状态机、分层状态机、行为树
https://www.cnblogs.com/zhanlang96/p/4793511.html 人工智能遵循着:感知->思考->行动决策方法:有限状态机(Finite-State Ma ...
- Java内部类介绍
在Java中,内部类包括:成员内部类(静态内部类.非静态内部类).匿名内部类.局部内部类(几乎不用). 1.成员内部类: 1.1非静态成员内部类 public class InnerClassTest ...
- awk 控制语句if-else
语法: 一.if (条件){语句}[else 语句] 单分支 二.if (条件){语句}else if( 条件){语句} 多分支 示例: .[root@localhost ~]# awk -F: '{ ...
- 应用安全 - 社工 - By 大数据 - shodan - 汇总
使用 | 命令 搜索语法 hostname: 搜索指定的主机或域名,例如 hostname:”google” port: 搜索指定的端口或服务,例如 port:”” country: 搜索指定的国家, ...
- Layer 弹出层抖动问题
layer.open({ type: 2, anim: 5,//加上anim,渐显 title: '品牌列表', shadeClose: fal ...
- python 并发编程 基于线程池实现并发的套接字通信
不应该让服务端随着 并发的客户端数量增多,而无数起线程,应该用线程池,限制线程数量,控制最大并发数 io密集型程序,最大并发数是2 客户端 from socket import * client = ...
- HDU 5437 & ICPC 2015 Changchun Alisha's Party(优先队列)
Alisha’s Party Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- tableau分布式添加节点
参考: 两节点的安装:https://zhuanlan.zhihu.com/p/44732932https://help.tableau.com/current/server-linux/zh-cn/ ...