传送门

题意:

现在有\(n\)堆石子,每堆石子有\(a_i\)个。

之后会有\(m\)次,每次选择\([l,r]\)的石子堆中的石子扔\(k\)个,若不足,则尽量扔。

现在输出\(1\)~\(m\)次,每次最多能取到多少石子(输出第\(i\)次的情况时,要考虑前\(i-1\)次)。

给出的区间不存在包含关系。

思路:

稍微暴力点想就是一个二分图,将\(k_i\)拆在左边,然后石子在右边,每次最大匹配。

但这做法显然不可行,时间复杂度不能承受。

这种一般就考虑\(hall\)定理:假设前面都满足的情况下,如果现在新加进来一段区间,假设我们取走\(k\)个石子,那么就是现在要满足最大匹配,因为也不能影响前面取的,那么现在所有包含\([l,r]\)的区间都要满足:取石子的量不超过石子个数。

这理解了这个题基本就做出来了,接下来就是维护信息。

定义\(a_i:\)右端点不超过\(i\)的所有区间的需求量;

定义\(b_i:\)左端点不超过\(i\)的所有区间的需求量;

定义\(s_i:1\)~\(i\)堆石子的个数和。

那么一段区间的需求量即为:\(a_r-b_{l-1}\)。

将上面说的一大段话形式化就有:

对于所有的\(l < r:a_r-b_{l-1}\leq s_r-s_{l-1}\),移项:\(s_r-a_r\geq s_{l-1}-b_{l-1}\)。

令\(f_i=s_i-a_i,g_i=s_i-b_i\)。

当我们在区间\([l,r]\)中新增需求时,会减小\(f\),所以\(k_i=min(k_i,f_R-g_L),L\leq l-1,R\geq r\)。

那么我们只需要维护\(f\)的后缀最小值和\(g\)的前缀最大值即可。

需求确定后,对\(f_{r..n},g_{l..n}\)都有影响,是一个区间修改问题。

所以线段树维护一下即可。

写得可能有点乱。。总之就是理解那一大段话,知道\(hall\)定理怎么用的,其它也比较好出来。。

代码如下:

/*
* Author: heyuhhh
* Created Time: 2019/11/6 16:25:01
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 40005; int n, m;
int a[N]; int f[N << 2], g[N << 2];
int lzf[N << 2], lzg[N << 2]; void push_up(int o) {
f[o] = min(f[o << 1], f[o << 1|1]);
g[o] = max(g[o << 1], g[o << 1|1]);
} void push_down(int o) {
if(lzf[o] != 0) {
f[o << 1] += lzf[o];
f[o << 1|1] += lzf[o];
lzf[o << 1] += lzf[o];
lzf[o << 1|1] += lzf[o];
lzf[o] = 0;
}
if(lzg[o] != 0) {
g[o << 1] += lzg[o];
g[o << 1|1] += lzg[o];
lzg[o << 1] += lzg[o];
lzg[o << 1|1] += lzg[o];
lzg[o] = 0;
}
} void build(int o, int l, int r) {
if(l == r) {
f[o] = g[o] = a[l];
return;
}
int mid = (l + r) >> 1;
build(o << 1, l, mid); build(o << 1|1, mid + 1, r);
push_up(o);
} void updf(int o, int l, int r, int L, int R, int v) {
if(L <= l && r <= R) {
f[o] += v;
lzf[o] += v;
return;
}
push_down(o);
int mid = (l + r) >> 1;
if(L <= mid) updf(o << 1, l, mid, L, R, v);
if(R > mid) updf(o << 1|1, mid + 1, r, L, R, v);
push_up(o);
} void updg(int o, int l, int r, int L, int R, int v) {
if(L <= l && r <= R) {
g[o] += v;
lzg[o] += v;
return;
}
push_down(o);
int mid = (l + r) >> 1;
if(L <= mid) updg(o << 1, l, mid, L, R, v);
if(R > mid) updg(o << 1|1, mid + 1, r, L, R, v);
push_up(o);
} int queryf(int o, int l, int r, int L, int R) {
if(L <= l && r <= R) return f[o];
push_down(o);
int mid = (l + r) >> 1;
int res = INF;
if(L <= mid) res = queryf(o << 1, l, mid, L, R);
if(R > mid) res = min(res, queryf(o << 1|1, mid + 1, r, L, R));
return res;
} int queryg(int o, int l, int r, int L, int R) {
if(L <= l && r <= R) return g[o];
push_down(o);
int mid = (l + r) >> 1;
int res = -INF;
if(L <= mid) res = queryg(o << 1, l, mid, L, R);
if(R > mid) res = max(res, queryg(o << 1|1, mid + 1, r, L, R));
return res;
} void run(){
cin >> n;
int x, y, z, p; cin >> x >> y >> z >> p;
for(int i = 1; i <= n; i++) {
a[i] = ((i - x) * (i - x) + (i - y) * (i - y)
+ (i - z) * (i - z)) % p, a[i] += a[i - 1];
}
build(1, 0, n);
cin >> m;
cin >> a[1] >> a[2] >> x >> y >> z >> p;
for(int i = 3; i <= m; i++) a[i] = (a[i - 1] * x + a[i - 2] * y + z) % p;
for(int i = 1; i <= m; i++) {
int l, r; cin >> l >> r;
a[i] = min(a[i], queryf(1, 0, n, r, n) - queryg(1, 0, n, 0, l - 1));
updf(1, 0, n, r, n, -a[i]);
updg(1, 0, n, l, n, -a[i]);
cout << a[i] << '\n';
}
} int main() {
//freopen("../input.in", "r", stdin);
//freopen("../output.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}

【BZOJ2138】stone(线段树+hall定理)的更多相关文章

  1. BZOJ1135:[POI2009]Lyz(线段树,Hall定理)

    Description 初始时滑冰俱乐部有1到n号的溜冰鞋各k双.已知x号脚的人可以穿x到x+d的溜冰鞋. 有m次操作,每次包含两个数ri,xi代表来了xi个ri号脚的人.xi为负,则代表走了这么多人 ...

  2. bzoj 1135 [POI2009]Lyz 线段树+hall定理

    1135: [POI2009]Lyz Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 573  Solved: 280[Submit][Status][ ...

  3. BZOJ 1135 P3488 LYZ-Ice Skates 线段树+Hall

    https://www.luogu.org/problem/P3488 根据Hall定理 左边任意一个区间L-R a[i]的和sum[l~r] 都要<= (R-L+1+d)*K 把(R-L+1) ...

  4. 【题解】 bzoj1135: [POI2009]Lyz (线段树+霍尔定理)

    题面戳我 Solution 二分图是显然的,用二分图匹配显然在这个范围会炸的很惨,我们考虑用霍尔定理. 我们任意选取穿\(l,r\)的号码鞋子的人,那么这些人可以穿的鞋子的范围是\(l,r+d\),这 ...

  5. 【题解】 bzoj3693: 圆桌会议 (线段树+霍尔定理)

    bzoj3693 Solution: 显然我们可以把人和位置抽象成点,就成了一个二分图,然后就可以用霍尔定理判断是否能有解 一开始我随便YY了一个\(check\)的方法:就是每次向后一组,我们就把那 ...

  6. 【BZOJ2138】stone(线段树,Hall定理)

    [BZOJ2138]stone(线段树,Hall定理) 题面 BZOJ 题解 考虑一个暴力. 我们对于每堆石子和每个询问,显然是匹配的操作. 所以可以把石子拆成\(a_i\)个,询问点拆成\(K_i\ ...

  7. 【BZOJ2138】stone Hall定理+线段树

    [BZOJ2138]stone Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆包含Ai颗石子.每1分钟,Nan会 ...

  8. [BZOJ2138]stone(Hall定理,线段树)

    Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆 包含Ai颗石子.每1分钟,Nan会在编号在\([L_i,R_i] ...

  9. [BZOJ2138]stone[霍尔定理+线段树]

    题意 一共有 \(n\) 堆石子,每堆石子有一个数量 \(a\) ,你要进行 \(m\) 次操作,每次操作你可以在满足前 \(i-1\) 次操作的回答的基础上选择在 \([L_i,R_i]\) 区间中 ...

随机推荐

  1. Spring 事务 属性 详细

    学习东西要知行合一,如果只是知道理论而没实践过,那么掌握的也不会特别扎实,估计过几天就会忘记,接下来我们一起实践来学习Spring事务的传播属性. 传播属性 传播属性定义的是当一个事务方法碰到另一个事 ...

  2. MongoDB 不在开源了,使用 Homebrew 安装只能玩社区版了

    使用了大半年的 mongodb ,最近在公司的新项目中应用,在 mac 上安装 mongodb 时发现始终安装不了,一直在报下面这样的错误: brew install mongodb 升级 brew  ...

  3. android binder 进程间通信机制2 - Binder进程间通信库实现原理

    1.Service组件 使用模板类BnInterface描述,称为Binder本地对象,对应于Binder驱动程序中的Binder实体对象 实现原理图如下:

  4. postman---Postman配置环境变量和全局变量

    我们在测试的过程中,遇到最多的问题也可以是环境的问题了吧,今天开发用了这个测试环境,明天又换了另一个测试环境,这样对于我们测试非常的麻烦,特别最接口的时候需要来回的输入环境地址比较麻烦,今天我们看看强 ...

  5. 【西北师大-2108Java】第九次作业成绩汇总

    [西北师大-2108Java]第九次作业成绩汇总 作业题目 面向对象程序设计(JAVA) 第11周学习指导及要求 实验目的与要求 (1)理解泛型概念: (2)掌握泛型类的定义与使用: (3)掌握泛型方 ...

  6. vue项目实现路由按需加载的3种方式

    vue异步组件技术 ==== 异步加载vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件 /* vue异步组件技术 */ { ...

  7. nui-app 笔记

    https://uniapp.dcloud.io

  8. 使用csv模块读写csv格式文件

    import csv class HandleCsv: ''' csv文件处理类 ''' def __init__(self, filename): ''' 构造器 :param filename: ...

  9. jQuery 源码分析(十一) 队列模块 Queue详解

    队列是常用的数据结构之一,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队).特点是先进先出,最先插入的元素最先被删除. 在jQuery内部,队列模块为动画模块提供基 ...

  10. 遍历json数据的几种方式

    json(JavaScript Object Notation),json是一种多用于存储和交换文本信息的语法.他能够进行数据的传输,通常和ajax一起使用.它具有体积小.速度快,易解析等诸多优点. ...