BZOJ 3681 线段树合并+网络流
2024-09-06 18:39:26
思路:
暴力建图有n*m条边
考虑怎么优化
(那就只能加个线段树了呗)
然后我就不会写了.....
抄了一波题解
//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=,M=N*,inf=0x3f3f3f3f;
vector<int>vec[N];
int n,m,first[M],next[M],v[M],w[M],tot,cnt=,S=,T=;
int lson[M],rson[M],root[N],jy,vis[M];
int read(){
char p=getchar();int x=;
while(p<''||p>'')p=getchar();
while(p>=''&&p<='')x=x*+p-'',p=getchar();
return x;
}
void Add(int x,int y,int z){v[tot]=y,w[tot]=z,next[tot]=first[x],first[x]=tot++;}
void add(int x,int y,int z){Add(x,y,z),Add(y,x,);}
int insert(int l,int r,int pos,int num){
pos=++cnt;
if(l==r){add(cnt,T,);return pos;}
int mid=(l+r)>>;
if(mid<num)add(pos,rson[pos]=insert(mid+,r,rson[pos],num),inf);
else add(pos,lson[pos]=insert(l,mid,lson[pos],num),inf);
return pos;
}
int merge(int l,int r,int pos,int last){
if(pos*last==)return pos+last;
int now=++cnt,mid=(l+r)>>;
if(l==r){add(now,pos,inf),add(now,last,inf);return now;}
add(now,lson[now]=merge(l,mid,lson[pos],lson[last]),inf);
add(now,rson[now]=merge(mid+,r,rson[pos],rson[last]),inf);
return now;
}
void dfs(int x){
for(int i=;i<vec[x].size();i++)
dfs(vec[x][i]),root[x]=merge(,n,root[x],root[vec[x][i]]);
}
void query(int l,int r,int pos,int L,int R){
if(!pos)return;
if(l>=L&&r<=R){add(cnt,pos,inf);return;}
int mid=(l+r)>>;
if(mid<L)query(mid+,r,rson[pos],L,R);
else if(mid>=R)query(l,mid,lson[pos],L,R);
else query(l,mid,lson[pos],L,R),query(mid+,r,rson[pos],L,R);
}
bool tell(){
memset(vis,-,sizeof(vis));
queue<int>q;q.push(S),vis[S]=;
while(!q.empty()){
int t=q.front();q.pop();
for(int i=first[t];~i;i=next[i])
if(vis[v[i]]==-&&w[i])vis[v[i]]=vis[t]+,q.push(v[i]);
}return ~vis[T];
}
int zeng(int x,int y){
if(x==T)return y;
int r=;
for(int i=first[x];~i;i=next[i])if(vis[v[i]]==vis[x]+&&w[i]){
int t=zeng(v[i],min(w[i],y-r));
w[i]-=t,w[i^]+=t,r+=t;
}if(!r)vis[x]=-;
return r;
}
int flow(){int ans=;while(tell())while(jy=zeng(S,inf))ans+=jy;return ans;}
int main(){
memset(first,-,sizeof(first));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)vec[read()].push_back(i);
for(int i=;i<=n;i++)root[i]=insert(,n,root[i],read());
dfs();
for(int i=;i<=m;i++){
int l=read(),r=read(),x=read(),y=read();
cnt++,add(S,cnt,y),query(,n,root[x],l,r);
}
printf("%d\n",flow());
}
最新文章
- HBase笔记:对HBase原理的简单理解
- java动态编译笔记
- BZOJ-2127-happiness(最小割)
- 【JS】点击目标外事件与IFRAM自适应高度
- OPENGL的入门第一个程序——Hello World
- Android回调接口的写法
- 双击vbs时,默认cscript运行脚本
- Js 数组——filter()、map()、some()、every()、forEach()、lastIndexOf()、indexOf()
- 基于jsoup的Java服务端http(s)代理程序-代理服务器Demo
- 变量的声明和定义以及extern的用法
- 自己动手编写IOC框架(二)
- [SCOI2008]天平
- C#工具:WebAPI常见问题及解决方案
- 前端----css的继承性和层叠性
- mysql-5.7.19 压缩安装 设置密码
- bootstrap 通过js代码创建和关闭插件
- javascript高级语法学习
- Java如何创建用户自定义异常?
- shell脚本通过expect脚本实现自动输入密码(使用expect)
- 关于Amazon.com Seller 网络以及IP地址更换 官方回答