bzoj3638
费用流+线段树
看见这个题我们马上就能想到费用流,设立源汇,分别向每个点连接容量为1费用为0的边,然后相邻的点之间连边,费用为点权,跑费用流就行了,但是很明显这样会超时,那么我们要优化一下,我们观察费用流的过程,发现对于点与点之间的边,每次取一段区间相当于把正向边改为反向边,费用变负,于是我们可以用线段树来模拟这个过程,像费用流一样贪心地选取区间的最大子段和,然后取反,每次取k次,然后恢复。这样就好了
但是写的时候有很多问题,比如如何返回一个区间?结构体!参考了popoqqq大神的代码,发现我们可以通过重载小于号直接对结构体取max,这样就十分好写了
然后这道题有点卡常,一定要在重载的时候把传入参数变成const+引用,这样在cf上快了200ms
这就是传说中的五倍经验吗
#include<bits/stdc++.h>
using namespace std;
const int N = ;
namespace IO
{
const int Maxlen = N * ;
char buf[Maxlen], *C = buf;
int Len;
inline void read_in()
{
Len = fread(C, , Maxlen, stdin);
buf[Len] = '\0';
}
inline void fread(int &x)
{
x = ;
int f = ;
while (*C < '' || '' < *C) { if(*C == '-') f = -; ++C; }
while ('' <= *C && *C <= '') x = (x << ) + (x << ) + *C - '', ++C;
x *= f;
}
inline void read(int &x)
{
x = ;
int f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << ) + (x << ) + c - ''; c = getchar(); }
x *= f;
}
inline void read(long long &x)
{
x = ;
long long f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << 1ll) + (x << 3ll) + c - ''; c = getchar(); }
x *= f;
}
} using namespace IO;
struct data {
int l, r, v;
data() {}
data(int l, int r, int v) : l(l), r(r), v(v) {}
friend bool operator < (const data &a, const data &b) { return a.v < b.v; }
friend data operator + (const data &a, const data &b) { return data(a.l, b.r, a.v + b.v); }
};
struct node {
data lmax, rmax, mx, mn, lmin, rmin, sum;
int tag;
node() {}
node(int x, int v) {
lmax = rmax = mx = mn = lmin = rmin = sum = data(x, x, v);
}
friend node operator + (const node &a, const node &b) {
node c;
if(a.tag == -) return b;
if(b.tag == -) return a;
c.tag = ;
c.sum = a.sum + b.sum;
c.lmax = max(a.lmax, a.sum + b.lmax);
c.lmin = min(a.lmin, a.sum + b.lmin);
c.rmax = max(b.rmax, a.rmax + b.sum);
c.rmin = min(b.rmin, a.rmin + b.sum);
c.mx = max(max(a.mx, b.mx), a.rmax + b.lmax);
c.mn = min(min(a.mn, b.mn), a.rmin + b.lmin);
return c;
}
} tree[N << ], st[];
int n, q;
int a[N];
void paint(node &o)
{
swap(o.lmax, o.lmin);
swap(o.rmax, o.rmin);
swap(o.mx, o.mn);
o.sum.v *= -;
o.lmax.v *= -;
o.lmin.v *= -;
o.rmax.v *= -;
o.rmin.v *= -;
o.mx.v *= -;
o.mn.v *= -;
o.tag ^= ;
}
void pushdown(int x)
{
if(tree[x].tag <= ) return;
paint(tree[x << ]);
paint(tree[x << | ]);
tree[x].tag ^= ;
}
void build(int l, int r, int x)
{
if(l == r)
{
tree[x] = node(l, a[l]);
return;
}
int mid = (l + r) >> ;
build(l, mid, x << );
build(mid + , r, x << | );
tree[x] = tree[x << ] + tree[x << | ];
}
node query(int l, int r, int x, int a, int b)
{
if(l > b || r < a) return tree[];
if(l >= a && r <= b) return tree[x];
pushdown(x);
int mid = (l + r) >> ;
return (query(l, mid, x << , a, b)) + (query(mid + , r, x << | , a, b));
}
void reverse(int l, int r, int x, int a, int b)
{
if(l > b || r < a) return;
if(l >= a && r <= b)
{
paint(tree[x]);
return;
}
pushdown(x);
int mid = (l + r) >> ;
reverse(l, mid, x << , a, b);
reverse(mid + , r, x << | , a, b);
tree[x] = tree[x << ] + tree[x << | ];
}
void update(int l, int r, int x, int pos, int v)
{
if(l == r)
{
tree[x] = node(l, v);
return;
}
pushdown(x);
int mid = (l + r) >> ;
if(pos <= mid) update(l, mid, x << , pos, v);
else update(mid + , r, x << | , pos, v);
tree[x] = tree[x << ] + tree[x << | ];
}
int main()
{
read_in();
fread(n);
for(int i = ; i <= n; ++i) fread(a[i]);
tree[].tag = -;
build(, n, );
fread(q);
while(q--)
{
int opt, l, r, v;
fread(opt);
if(opt == )
{
fread(l);
fread(v);
update(, n, , l, v);
}
if(opt == )
{
fread(l);
fread(r);
fread(v);
int sum = , top = ;
while(v--)
{
node ans = query(, n, , l, r);
if(ans.mx.v <= ) break;
reverse(, n, , ans.mx.l, ans.mx.r);
node tmp = query(, n, , ans.mx.l, ans.mx.r);
st[++top] = ans;
sum += ans.mx.v;
}
printf("%d\n", sum);
for(int i = top; i; --i) reverse(, n, , st[i].mx.l, st[i].mx.r);
}
}
return ;
}
bzoj3638的更多相关文章
- 【BZOJ3638】Cf172 k-Maximum Subsequence Sum 线段树区间合并(模拟费用流)
[BZOJ3638]Cf172 k-Maximum Subsequence Sum Description 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交 ...
- 【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广
3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 174 Solved: 9 ...
- BZOJ3638[Codeforces280D]k-Maximum Subsequence Sum&BZOJ3272Zgg吃东西&BZOJ3267KC采花——模拟费用流+线段树
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
- [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)
https://www.cnblogs.com/DaD3zZ-Beyonder/p/5634149.html k可重区间集问题有两种建图方式,可能这一种才可以被线段树优化. 换个角度看,这也是一个类似 ...
- BZOJ3638|CodeForces 280D k-Maximum Subsequence Sum
题目链接:戳我 一类典型模型.线段树模拟网络流+区间最大K段和. 因为不会写,所以参考了黄学长的博客.但是我觉得他说得不够详细,所以想好好地解释一下: 前置技能1:区间最大子段和 如果K=1的时候怎么 ...
- 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
- bzoj3638 Cf172 k-Maximum Subsequence Sum
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3638 [题解] 看到k<=20就感觉很py了啊 我们用一棵线段树维护选段的过程,能选到 ...
- [转载]hzwer的bzoj题单
counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ120 ...
- BZOJ刷题列表【转载于hzwer】
沿着黄学长的步伐~~ 红色为已刷,黑色为未刷,看我多久能搞完吧... Update on 7.26 :之前咕了好久...(足见博主的flag是多么emmm......)这几天开始会抽时间刷的,每天几道 ...
随机推荐
- 把excel导入到mysql中
方法很多,不过建议你先看看mysql的开发文档,里面写的很详细的,如果你懒得看,可以看下面的 1.有个软件PHP Excel Parser Pro v4.2可以 2.可将Excel存成csv格式.然后 ...
- 进入一个jsp直接跳到另一个jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- Jquery操作事件
1.文档加载事件 2.DOM单击双击事件 3.DOM获得焦点,失去焦点问题 4.DOM鼠标移入,移出事件 <!DOCTYPE html> <html> <head> ...
- The Bottom of a Graph
poj——The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K ...
- POJ 1860【求解是否存在权值为正的环 屌丝做的第一道权值需要计算的题 想喊一声SPFA万岁】
题意: 有n种钱币,m个钱币兑换点,小明一开始有第n种钱币数量为w. 每个兑换点可以将两种不同的钱币相互兑换,但是兑换前要先收取一定的费用,然后按照比例兑换. 问小明是否可以经过一系列的兑换之后能够将 ...
- Ubuntu 16.04安装QQ(不一定成功)
注意1:如果是刚新装的系统,可以正常安装,但是,如果你已经装了很多软件,千万不要安装,因为会把系统上一般的依赖包和你之前装的软件全部卸载掉!甚至将桌面Dock都会卸载!最终只能重装Ubuntu解决. ...
- Eclipse导入Maven项目出现:Could not calculate build plan: Plugin org.apache.maven.plugins:maven-war-plugin:2.2
错误如下: Could not calculate build plan: Plugin org.apache.maven.plugins:maven-war-plugin:2.2 or one of ...
- 如何在不允许联网的环境下使用Maven开发
前言:Maven的运行机理是:Maven核心组件先去本地的.m2目录下的库中去寻找依赖或者插件,如果本地库里没有,如果配置了私服则上私服去下载依赖或者插件,如果私服上没有,则上中央服务等Maven服务 ...
- VS2015 android 设计器不能可视化问题解决。
近期安装了VS2015,体验了一下android 的开发,按模板创建执行了个,试下效果非常不错.也能够可视化设计.但昨天再次打开或创建一个android程序后,设计界面直接不能显示,显示错误:(可能是 ...
- Office PDF如何旋转页面之后保存
直接视图-旋转视图-逆时针,是不行的,旋转之后无法保存,另存为之后也再打开也没有效果. 要点击视图-工具-页面 然后在右边的菜单中点击旋转,然后执行旋转,然后就可以保存了.