BZOJ3681: Arietta
题解:
数据结构来优化网络流,貌似都是用一段区间来表示一个点,然后各种乱搞。。。
发现主席树好吊。。。在树上建主席树貌似有三种方法:
1.建每个点到根节点这条链上的主席树,可以回答和两点间的路径的XX问题。
2.按DFS序然后就成了序列上的主席树,可以回答子树第k大等XX问题。
3.先给每个点单独建立主席树,然后dfs下去,并且将一个点的所有子树合并起来,相当于新建了n棵主席树,但这样可以解决该题。。。
神犇勿喷。。。
因为这样从rt[x]查询到的区间就可以直接表示满足题意的点了,然后就是最大流了。
代码:
- #include<cstdio>
- #include<cstdlib>
- #include<cmath>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- #include<vector>
- #include<map>
- #include<set>
- #include<queue>
- #include<string>
- #define inf 1000000000
- #define maxn 100000+5
- #define maxm 1000000+5
- #define eps 1e-10
- #define ll long long
- #define pa pair<int,int>
- #define for0(i,n) for(int i=0;i<=(n);i++)
- #define for1(i,n) for(int i=1;i<=(n);i++)
- #define for2(i,x,y) for(int i=(x);i<=(y);i++)
- #define for3(i,x,y) for(int i=(x);i>=(y);i--)
- #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
- #define mod 1000000007
- #define mid ((l+r)>>1)
- using namespace std;
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
- while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
- return x*f;
- }
- int n,m,s,t,cnt,maxflow,tot=,head[maxm],cur[maxm],h[maxm];
- queue<int>q;
- int rt[maxn],lc[maxm],rc[maxm];
- struct edge{int go,next,v;}e[maxm];
- vector<int> son[maxn];
- inline void add(int x,int y,int v)
- {
- e[++tot]=(edge){y,head[x],v};head[x]=tot;
- e[++tot]=(edge){x,head[y],};head[y]=tot;
- }
- bool bfs()
- {
- for(int i=;i<=cnt;i++)h[i]=-;
- q.push(s);h[s]=;
- while(!q.empty())
- {
- int x=q.front();q.pop();
- for(int i=head[x];i;i=e[i].next)
- if(e[i].v&&h[e[i].go]==-)
- {
- h[e[i].go]=h[x]+;q.push(e[i].go);
- }
- }
- return h[t]!=-;
- }
- int dfs(int x,int f)
- {
- if(x==t) return f;
- int tmp,used=;
- for(int i=cur[x];i;i=e[i].next)
- if(e[i].v&&h[e[i].go]==h[x]+)
- {
- tmp=dfs(e[i].go,min(e[i].v,f-used));
- e[i].v-=tmp;if(e[i].v)cur[x]=i;
- e[i^].v+=tmp;used+=tmp;
- if(used==f)return f;
- }
- if(!used) h[x]=-;
- return used;
- }
- void dinic()
- {
- maxflow=;
- while(bfs())
- {
- for (int i=;i<=cnt;i++)cur[i]=head[i];maxflow+=dfs(s,inf);
- }
- }
- inline void insert(int x)
- {
- int l,r;
- for(l=,r=n,++cnt;l<r;++cnt)
- if(x<=mid)
- {
- add(cnt,lc[cnt]=cnt+,inf);
- r=mid;
- }else
- {
- add(cnt,rc[cnt]=cnt+,inf);
- l=mid+;
- }
- add(cnt,t,);
- }
- inline int merge(int x,int y,int l,int r)
- {
- if(x*y==)return x+y;
- int k=++cnt;
- if(l==r)add(k,x,inf),add(k,y,inf);
- else
- {
- add(k,lc[k]=merge(lc[x],lc[y],l,mid),inf);
- add(k,rc[k]=merge(rc[x],rc[y],mid+,r),inf);
- }
- return k;
- }
- inline void dfs(int x)
- {
- if(!son[x].size())return;
- for(int i=son[x].size()-;~i;i--)
- {
- dfs(son[x][i]);
- rt[x]=merge(rt[x],rt[son[x][i]],,n);
- }
- }
- inline void query(int k,int l,int r,int x,int y)
- {
- if(!k)return;
- if(l==x&&r==y){add(cnt,k,inf);return;}
- if(y<=mid)query(lc[k],l,mid,x,y);
- else if(x>mid)query(rc[k],mid+,r,x,y);
- else query(lc[k],l,mid,x,mid),query(rc[k],mid+,r,mid+,y);
- }
- int main()
- {
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- n=read();m=read();s=;t=;cnt=t;
- for2(i,,n)son[read()].push_back(i);
- for1(i,n)rt[i]=cnt+,insert(read());
- dfs();
- while(m--)
- {
- int l=read(),r=read(),x=read(),y=read();
- add(s,++cnt,y);
- query(rt[x],,n,l,r);
- }
- dinic();
- cout<<maxflow<<endl;
- return ;
- }
3681: Arietta
Time Limit: 20 Sec Memory Limit: 64 MB
Submit: 64 Solved: 28
[Submit][Status]
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
1 1 2 2
5 3 2 4 1
1 3 2 1
3 5 1 4
Sample Output
HINT
第一个力度弹奏音符5,第二个力度弹奏音符1,2,4。
数据范围与约定
对于 100% 的数据,1 ≤ n, m ≤ 10000 。
对于所有数据1<=Hi,Ti,Pi<=N,1<=Li<=Ri<=N
Source
BZOJ3681: Arietta的更多相关文章
- [BZOJ3681]Arietta(可持久化线段树合并优化建图+网络流)
暴力建图显然就是S->i连1,i->j'连inf(i为第j个力度能弹出的音符),j'->T连T[j]. 由于是“某棵子树中权值在某区间内的所有点”都向某个力度连边,于是线段树优化建图 ...
- bzoj3681: Arietta(网络流)
传送门 主席树优化建图? 然而我连代码都看不懂 贴个题解好了->这里 //minamoto #include<iostream> #include<cstdio> #in ...
- 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流
[BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...
- 【BZOJ-3681】Arietta 网络流 + 线段树合并
3681: Arietta Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 182 Solved: 70[Submit][Status][Discuss ...
- 【BZOJ 3681】Arietta
传送门 题目描述 Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中. 但是她从未停止过和恋人 Velding 的书信往来.一天,她准备去探访他. 对着窗外的阳光,临 ...
- bzoj 3681 Arietta
一棵有根树,每个点有一个音高,有 $m$ 中弹奏方法,每种方法可以弹奏 $d$ 子树中音高在 $[l,r]$ 间的音符,每种方法最多弹 $t$ 次 求最多能弹出多少个音符 $n \leq 10000$ ...
- CH Round #51 - Shinrein祭 #1
A.Phorni 题目:http://www.contesthunter.org/contest/CH%20Round%20%2351%20-%20Shinrein祭%20%231/Phorni 没做 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- tomcat内存溢出,设置
tomcat/bin/catalina.bat里找到echo Using CATALINA_BASE: "%CATALINA_BASE%" ,在上方设置: set JAV ...
- 一些牛逼的统计SQL
SQL 1.查询连续2天,每天发帖大于等于2次的用户 SELECT USER_ID FROM ( SELECT USER_ID, DATEDIFF(CREATE_TIME, '1971-01-01') ...
- HtmlAgilityPack 简单运用
WebClient client = new WebClient(); MemoryStream ms = new MemoryStream(client.DownloadData("htt ...
- 汇编语言中"[]"的用法
"[]"的用法在"常见问题"已经有所说明,引用如下: 1.push dword ptr [024c1100] 压栈024c1100值的双字 2.cmp eax, ...
- hdu 4901
一个简单的dp,比赛的时候太坚信自己的小聪明没用二维数组一直WA到死: #include<cstdio> #include<cstring> #define maxn 1009 ...
- 11个实用jQuery日历插件
1. FullCalendar FullCalendar是很出名的jQuery日历插件,它支持拖拽等功能,整合了Google Calendar,而且可以通过JSON来绑定事件,设计师可以轻松地自定义日 ...
- Application.persistentDataPath 的一个小坑
打包之前在Android的Player Setting里面选择WriteAccess (写入访问) Internal Only:表示Application.persistentDataPath的路径是 ...
- properties配置应用,为什么需要使用properties文件
在项目中我们常常会使用Constants常量类,达到系统全局配置的目的. 但是有些常量需要动态的配置,如果项目上线后,每次修改Constants.java然后再编译,再上传Constants.clas ...
- 【redis】05Redis的常用命令及高级应用
Redis常用命令 Redis提供了非常丰富的命令,对数据库和个中数据类型进行操作, 这些命令呢,可以在Linux终端使用. 分为两大类的命令,一种是键值相关的命令,一种是服务器相关的命令, ...
- VS2010 MFC DataGrid绑定实例
VS2010环境下MFC使用DataGrid绑定数据源 参考:http://blog.csdn.net/fddqfddq/article/details/7874706 详细介绍如何在MFC中使用Da ...