3681: Arietta

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 182  Solved: 70
[Submit][Status][Discuss]

Description

Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中。
但是她从未停止过和恋人 Velding 的书信往来。一天,她准备去探访他。
对着窗外的阳光,临行前她再次弹起了琴。
她的琴的发声十分特殊。
让我们给一个形式化的定义吧。
所有的 n 个音符形成一棵由音符 C ( 1 号节点) 构成的有根树,每一个音符有一个音高 Hi 。
Arietta 有 m 个力度,第 i 个力度能弹出 Di 节点的子树中,音高在 [Li,Ri] 中的任意一个音符。
为了乐曲的和谐,Arietta 最多会弹奏第 i 个力度 Ti 次。
Arietta 想知道她最多能弹出多少个音符。

Input

输入共 m + 3 行。
第一行两个整数 n, m ,意义如题目所述。
第二行 n - 1 个整数 Pi ,表示节点 i ( i = 2 . . . n ) 的父亲节点的编号。
第三行 n 个整数 Hi 。
接下来的 m 行,每行四个整数 Li,Ri,D,Ti

Output

输出一个整数表示 Arietta 最多能弹奏多少音符。
数据范围与约定
对于 100% 的数据,1 ≤ n, m ≤ 10000 。
对于所有数据,1 ≤ Hi , Ti , Pi ≤ n, 1 ≤ Li ≤ Ri ≤ n 。

Sample Input

5 2
1 1 2 2
5 3 2 4 1
1 3 2 1
3 5 1 4

Sample Output

4

HINT

第一个力度弹奏音符5,第二个力度弹奏音符1,2,4。

数据范围与约定

对于 100% 的数据,1 ≤ n, m ≤ 10000 。

对于所有数据1<=Hi,Ti,Pi<=N,1<=Li<=Ri<=N

Source

Shinrein祭 #1

Solution

怎么看都和A+B problem很类似,所以肯定是 主席树优化构图 + 网络流

这样的树形态主席树,用线段树合并会很方便得到每个子树对应的主席树形态,注意一下细节就好了,数组大小得斟酌着开!!!..

这样的话,点数大概是$O(2NlogN+M)$级,边数大概在$O(2NlogN+MlogL)$级。

但是这题内存64M还是有点小卡的..一开始没有判断lson和rson是否存在就直接连边了,造成连了大量无用的边,MLE了一次,在连边的时候注意一下是否有意义即可。

不知道程序里好像有什么奇怪的地方..本机拍一组大样例RE..因为连边时有某个点编号连完后变大了10倍..其余的应该是没什么问题..谁知道这沙茶程序出了啥毛病(捂脸

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} #define MAXN 400010
#define INF 0x7fffffff int N,M,sz=1; struct EdgeNode{
int next,to,cap;
}edge[1000010];
int head[MAXN],cnt=1;
inline void AddEdge(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].cap=w;}
inline void InsertEdge(int u,int v,int w) {/*printf("<%d,%d>%d\n",u,v,w);*/ AddEdge(u,v,w); AddEdge(v,u,0);} int h[MAXN],cur[MAXN],S,T;
queue<int>q;
inline bool Bfs()
{
for (int i=0; i<=sz; i++) h[i]=-1;
q.push(S); h[S]=0;
while (!q.empty()) {
int now=q.front(); q.pop();
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && h[edge[i].to]==-1)
h[edge[i].to]=h[now]+1,q.push(edge[i].to);
}
return h[T]!=-1;
} inline int Dfs(int now,int low)
{
if (now==T) return low;
int w,used=0;
for (int i=cur[now]; i; i=edge[i].next)
if (edge[i].cap && h[edge[i].to]==h[now]+1) {
int w=Dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^1].cap+=w; used+=w;
if (used==low) return used;
if (edge[i].cap) cur[now]=i;
}
if (!used) h[now]=-1;
return used;
} inline int Dinic()
{
int re=0;
while (Bfs()) {
for (int i=0; i<=sz; i++) cur[i]=head[i];
re+=Dfs(S,INF);
}
return re;
} struct SgtNode{
int lson,rson;
}tree[10010*80]; int root[MAXN];
inline void Insert(int &x,int l,int r,int pos)
{
x=++sz;
if (l==r) {
InsertEdge(x,T,1);
return;
}
int mid=(l+r)>>1;
if (pos<=mid) Insert(tree[x].lson,l,mid,pos),InsertEdge(x,tree[x].lson,INF);
else Insert(tree[x].rson,mid+1,r,pos),InsertEdge(x,tree[x].rson,INF);
} inline int Merge(int x,int y,int l,int r)
{
if (!x || !y) return x|y;
int z=++sz;
if (l==r) {
InsertEdge(z,x,INF),InsertEdge(z,y,INF);
return z;
}
int mid=(l+r)>>1;
tree[z].lson=Merge(tree[x].lson,tree[y].lson,l,mid);
if (tree[z].lson) InsertEdge(z,tree[z].lson,INF);
tree[z].rson=Merge(tree[x].rson,tree[y].rson,mid+1,r);
if (tree[z].rson) InsertEdge(z,tree[z].rson,INF);
return z;
} inline void Query(int x,int l,int r,int L,int R,int id)
{
if (!x) return;
if (L<=l && R>=r) {
InsertEdge(id,x,INF);
return;
}
int mid=(l+r)>>1;
if (L<=mid) Query(tree[x].lson,l,mid,L,R,id);
if (R>mid) Query(tree[x].rson,mid+1,r,L,R,id);
} vector<int>son[MAXN];
inline void DFS(int now)
{
for (int i=0; i<son[now].size(); i++) {
DFS(son[now][i]);
root[now]=Merge(root[now],root[son[now][i]],1,N);
}
} int main()
{ N=read(),M=read(); for (int i=2,x; i<=N; i++) x=read(),son[x].push_back(i); S=0,T=1; for (int i=1,x; i<=N; i++) x=read(),Insert(root[i],1,N,x); DFS(1); for (int i=1; i<=M; i++) {
int L=read(),R=read(),D=read(),Ti=read();
InsertEdge(S,++sz,Ti); Query(root[D],1,N,L,R,sz);
} printf("%d\n",Dinic()); return 0;
}

  

【BZOJ-3681】Arietta 网络流 + 线段树合并的更多相关文章

  1. BZOJ.3545.[ONTAK2010]Peaks(线段树合并)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. \(Solut ...

  2. bzoj 4631: 踩气球 线段树合并

    4631: 踩气球 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 265  Solved: 136[Submit][Status][Discuss] ...

  3. BZOJ:5457: 城市(线段树合并)(尚待优化)

    5457: 城市 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 18  Solved: 12[Submit][Status][Discuss] Des ...

  4. bzoj 4756 Promotion Counting —— 线段树合并

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4756 合并子树的权值线段树: merge 返回 int 或者是 void 都可以. 代码如下 ...

  5. [BZOJ3681]Arietta(可持久化线段树合并优化建图+网络流)

    暴力建图显然就是S->i连1,i->j'连inf(i为第j个力度能弹出的音符),j'->T连T[j]. 由于是“某棵子树中权值在某区间内的所有点”都向某个力度连边,于是线段树优化建图 ...

  6. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

  7. BZOJ.4399.魔法少女LJJ(线段树合并)

    BZOJ 注意\(c\leq7\)→_→ 然后就是裸的权值线段树+线段树合并了. 对于取\(\max/\min\)操作可以直接区间修改清空超出范围的值,然后更新到对应位置上就行了(比如对\(v\)取\ ...

  8. BZOJ.5461.[PKUWC2018]Minimax(DP 线段树合并)

    BZOJ LOJ 令\(f[i][j]\)表示以\(i\)为根的子树,权值\(j\)作为根节点的概率. 设\(i\)的两棵子树分别为\(x,y\),记\(p_a\)表示\(f[x][a]\),\(p_ ...

  9. BZOJ.3307.雨天的尾巴(dsu on tree/线段树合并)

    BZOJ 洛谷 \(dsu\ on\ tree\).(线段树合并的做法也挺显然不写了) 如果没写过\(dsu\)可以看这里. 对修改操作做一下差分放到对应点上,就成了求每个点子树内出现次数最多的颜色, ...

随机推荐

  1. 了解Linux操作系统的引导过程

    原文地址:http://os.51cto.com/art/200706/49690.htm 1.简介 Linux启动过程指的是从加电到看到shell提示的这一段时间. Linux启动的过程可以大概分为 ...

  2. Codeforces 906 D. Power Tower

    http://codeforces.com/contest/906/problem/D 欧拉降幂 #include<cstdio> #include<iostream> usi ...

  3. 51Nod 1684 子集价值 (平方和去括号技巧)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1684 题意: 新建一个位运算,求所有子集通过这个位运算后的答案的平方和是 ...

  4. Android改进版CoverFlow效果控件

    最近研究了一下如何在Android上实现CoverFlow效果的控件,其实早在2010年,就有Neil Davies开发并开源出了这个控件,Neil大神的这篇博客地址http://www.inter- ...

  5. CF359B Permutation (构造)

    CF359B Permutation \(solution:\) 作为一道构造题,这题也十分符合构造的一些通性----(找到一些规律,然后无脑循环). 构造一个长度为 \(2n\) 的排列 \(a\) ...

  6. Windows命令-系统木马取样

    1.前言 工作中偶尔会遇到去现场提取木马样本回公司分析的情况.如果是生产环境下,不方便安装各类抓包.安全软件时.能用系统自带的命令去定位出木马程序相关的信息是最理想不过的状态. 2.Windows常用 ...

  7. artDialog4.1.7 摘自网络

    jquery.artDialog.source.js学习 1 关键的对象关系 art = jQuery = $ function artDialog() {...} artDialog.fn = ar ...

  8. ConvertUtils.register的作用

    BeanUtils的populate方法或者getProperty,setProperty方法其实都会调用convert进行转换 但Converter只支持一些基本的类型,甚至连Java.util.D ...

  9. 《Look Mom, I don’t use Shellcode》议题解析

    0x0 前言 <Look Mom, I don’t use Shellcode>是2016年Syscan360上讲过的一个议题,这个议题的副标题是"Browser Exploit ...

  10. C#数组 List、Dictionary 、Arrary、ArrayList

    #region Dictionary 泛型集合,动态修改查询.查询和排序 Dictionary<string, string> dic = new Dictionary<string ...