# bzoj 4842 [Neerc2016]Delight for a Cat

### Description

ls是一个特别堕落的小朋友，对于n个连续的小时，他将要么睡觉要么打隔膜，一个小时内他不能既睡觉也打隔膜，因此一个小时内他只能选择睡觉或者打隔膜，当然他也必须选择睡觉或打隔膜，对于每一个小时，他选择睡觉或打隔膜的愉悦值是不同的，对于第i个小时，睡觉的愉悦值为si，打隔膜的愉悦值为ei，同时又有一个奥妙重重的规定：对于任意一段连续的k小时，ls必须至少有t1时间在睡觉，t2时间在打隔膜。那么ls想让他获得的愉悦值尽量大，他该如何选择呢？

### Output

#### Sample Input

10 4 1 2

1 2 3 4 5 6 7 8 9 10

10 9 8 7 6 5 4 3 2 1

69

EEESESEESS

### 题解

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#define M 200100
#define N 100100
#define inf 1e17
#define min(x,y) ((x<y)?(x):(y))
using namespace std;
typedef pair<long long, long long> Pair;
struct MFMC {
struct node {
int from, to, next;
long long cost, flow;
}e[M];
int tot, st[N];
int pe[N], pv[N], vis[N];
long long dis[N];
void init() {
tot = -1, memset(e, -1, sizeof e);
memset(st, -1, sizeof st);
}
void add(int x, int y, long long z, long long zz) {
e[++tot].to = y, e[tot].from = x;
e[tot].flow = z, e[tot].cost = zz;
e[tot].next = st[x], st[x] = tot;
}
void add_edge(int x, int y, long long z, long long zz) {
}
queue <int> que;
bool spfa(int S, int T) {
//      memset(dis, 0x33, sizeof dis);
for (int i = 0; i <= T; ++i)
dis[i] = inf;
memset(vis, 0, sizeof vis);
que.push(S), vis[S] = 1, dis[S] = 0;
while(!que.empty()) {
int now = que.front();
que.pop();
vis[now] = 0;
for (int i = st[now]; ~i; i = e[i].next)
if (e[i].flow > 0 && dis[e[i].to] > dis[now] + e[i].cost) {
dis[e[i].to] = dis[now] + e[i].cost;
pe[e[i].to] = i, pv[e[i].to] = now;
if (!vis[e[i].to])
vis[e[i].to] = 1, que.push(e[i].to);
}
}
return dis[T] < inf;
}
Pair mfmc(int S, int T) {
long long COST = 0, FLOW = 0, flow;
while(spfa(S, T)) {
flow = inf;
for (int i = T; i != S; i = pv[i])
flow = min(flow, e[pe[i]].flow);
COST += flow * dis[T];
FLOW += flow;
for (int i = T; i != S; i = pv[i])
e[pe[i]].flow -= flow, e[pe[i] ^ 1].flow += flow;
}
return make_pair(FLOW, COST);
}
}mcmf;
int n, m, k, x, y, z, t1, t2, a[N], b[N];
int main() {
mcmf.init();
scanf("%d%d%d%d", &n, &k, &t1, &t2);
long long sum = 0;
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]), sum += a[i];
for (int i = 1; i <= n; ++i)
scanf("%d", &b[i]);
int mins = t2, maxs = k - t1, s = n + 1, S = s + 1, T = S + 1;
for (int i = 1; i <= n; ++i)
mcmf.add_edge(i, i + k > n ? T : i + k, 1, -(b[i] - a[i]));
for (int i = 1; i <= n; ++i)
mcmf.add_edge(i, i + 1 > n ? T : i + 1, maxs - mins, 0);
for (int i = 1; i <= k; ++i)