传送门

题目描述

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的更多相关文章

  1. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  2. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  3. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  4. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  5. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  6. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  7. 【BZOJ 2132】圈地计划 && 【7.22Test】计划

    两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...

  8. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  9. 【BZOJ 1032】 [JSOI2007]祖码Zuma

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1032 [题意] [题解] /* 设f[i][j]表示从第i个珠子开始的j个珠子被消除; ...

随机推荐

  1. jquery.qrcode.min.js——前端生成二维码

    下载地址:[http://www.jq22.com/jquery-info294] demo1:[https://www.helloweba.com/view-blog-226.html] demo2 ...

  2. 【神经网络与深度学习】基于Windows+Caffe的Minst和CIFAR—10训练过程说明

    Minst训练 我的路径:G:\Caffe\Caffe For Windows\examples\mnist  对于新手来说,初步完成环境的配置后,一脸茫然.不知如何跑Demo,有么有!那么接下来的教 ...

  3. Akka系列(七):Actor持久化之Akka persistence

    前言.......... 我们在使用Akka时,会经常遇到一些存储Actor内部状态的场景,在系统正常运行的情况下,我们不需要担心什么,但是当系统出错,比如Actor错误需要重启,或者内存溢出,亦或者 ...

  4. MAS多媒体的整个存储架构是怎样的?

    MAS多媒体的整个存储架构是怎样的?

  5. AKKA学习(二) 未完

    Actor调用 从上面的例子中,我们可以大概的对AKKA在JAVA中的使用有一个全局的概念.这里我们在稍微细致的讲解一下. 在JAVA中使用AKKA进行开发主要有这几个步骤: 定义消息模型. 创建Ac ...

  6. Java中的享元设计模式,涨姿势了!

    首先来看一段代码: public class ShareTest {   public static void main(String[] args) {     Integer a = 127;   ...

  7. 洛谷 P2467 地精部落 题解

    题面 好难啊好难啊好难啊~(以后再玩魔兽的时候绝对绝对虐死他) 做完后总结了一下思路; 首先推一下以下三条性质: 1.若两个 i 与 i+1 不相邻,那么我们直接交换这两个数字就可以组成一个新的数列 ...

  8. CF 11D A Simple Task 题解

    题面 这道题的数据范围一看就是dfs或状压啦~ 本文以状压的方式来讲解 f[i][j]表示目前的节点是i,已经经历过的节点的状态为j的简单环的个数: 具体的转移方程和细节请看代码: PS:(i& ...

  9. 实例学习——爬取Pexels高清图片

    近来学习爬取Pexels图片时,发现书上代码会抛出ConnectionError,经查阅资料知,可能是向网页申请过于频繁被禁,可使用time.sleep(),减缓爬取速度,但考虑到爬取数据较多,运行时 ...

  10. Nginx教程(一)-全面认知

    什么是 nginx nginx 是一款高性能的 http 服务器,反向代理服务器,电子邮件(IMAP/POP3)代理服务器: 它的特点就是高性能,占用内存少,支持高并发,运行稳定: 官方测试 可支持 ...