CF1117G Recursive Queries
题意:给定一个序列,定义[l, r]的最大值在m处,求f(l, r) = f(l, m - 1) + (r - l + 1) + f(m + 1, r)。多次询问。100w。
解:考虑这个区间内每个数作为最大值的时候,它的(r - l + 1)的贡献。
显然就是min(r, rci - 1) - max(l, lci + 1) + 1
我们分别计算这两部分。
min(r, rci - 1)这个东西,发现当一个i的rci - 1比r小的时候,就会是一个定值。否则就是r。而我们要区间求和,于是开一个线段树。把询问挂在区间上从右往左扫,线段树每个位置维护rci - 1是否比当前的r小。如果比当前r大了,就改掉。
第二项同理。
#include <bits/stdc++.h>
typedef long long LL;
const int N = ;
struct Node {
int l, r, id;
}node[N];
int val[N], n, q, lc[N], rc[N], stk[N], top;
LL ans[N];
std::vector<int> v[N], v2[N];
LL sum[N << ], sum2[N << ];
inline void pushup(int o) {
sum[o] = sum[o << ] + sum[o << | ];
sum2[o] = sum2[o << ] + sum2[o << | ];
return;
}
void build(int f, int l, int r, int o) {
if(l == r) {
if(f == ) {
sum[o] = lc[r] + ;
}
else {
sum[o] = rc[r] - ;
}
sum2[o] = ;
return;
}
int mid = (l + r) >> ;
build(f, l, mid, o << );
build(f, mid + , r, o << | );
pushup(o);
return;
}
LL ask(int L, int R, int v, int l, int r, int o) {
if(L <= l && r <= R) {
return sum[o] + v * sum2[o];
}
int mid = (l + r) >> ;
LL ans = ;
if(L <= mid) ans = ask(L, R, v, l, mid, o << );
if(mid < R) ans += ask(L, R, v, mid + , r, o << | );
return ans;
}
void change(int p, int l, int r, int o) {
if(l == r) {
sum[o] = ;
sum2[o] = ;
return;
}
int mid = (l + r) >> ;
if(p <= mid) change(p, l, mid, o << );
else change(p, mid + , r, o << | );
pushup(o);
return;
}
int main() {
scanf("%d%d", &n, &q);
for(int i = ; i <= n; i++) {
scanf("%d", &val[i]);
}
for(int i = ; i <= q; i++) {
scanf("%d", &node[i].l);
node[i].id = i;
}
for(int i = ; i <= q; i++) {
scanf("%d", &node[i].r);
}
for(int i = ; i <= n; i++) {
while(top && val[stk[top]] <= val[i]) {
rc[stk[top]] = i;
top--;
}
lc[i] = stk[top];
stk[++top] = i;
}
while(top) {
rc[stk[top]] = n + ;
top--;
}
/// solve L
for(int i = ; i <= n; i++) {
v[lc[i]].push_back(i);
}
for(int i = ; i <= q; i++) {
v2[node[i].l].push_back(i);
}
build(, , n, );
for(int i = ; i <= n; i++) {
for(int j = ; j < (int)v[i - ].size(); j++) {
/// v[i - 1][j]
change(v[i - ][j], , n, );
}
for(int j = ; j < (int)v2[i].size(); j++) {
int x = v2[i][j];
ans[x] = -ask(node[x].l, node[x].r, i, , n, );
}
}
/// solve R
for(int i = ; i <= n; i++) {
v[i].clear();
v2[i].clear();
}
for(int i = ; i <= n; i++) {
v[rc[i]].push_back(i);
}
for(int i = ; i <= q; i++) {
v2[node[i].r].push_back(i);
}
build(, , n, );
for(int i = n; i >= ; i--) {
for(int j = ; j < (int)v[i + ].size(); j++) {
/// v[i + 1][j]
change(v[i + ][j], , n, );
}
for(int j = ; j < (int)v2[i].size(); j++) {
int x = v2[i][j];
ans[x] += ask(node[x].l, node[x].r, i, , n, );
}
}
for(int i = ; i <= q; i++) {
printf("%lld ", ans[i] + node[i].r - node[i].l + );
}
return ;
}
AC代码
CF1117G Recursive Queries的更多相关文章
- sql script: Graphs, Trees, Hierarchies and Recursive Queries
--------------------------------------------------------------------- -- Inside Microsoft SQL Server ...
- sql server: Graphs, Trees, Hierarchies and Recursive Queries
--------------------------------------------------------------------- -- Chapter 09 - Graphs, Trees, ...
- Codeforces 932.B Recursive Queries
B. Recursive Queries time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- 笔记-Recursive Queries
Recursive Queries \[m_{l,r}=\textrm{id}(\max_{i=l}^r a_i)\\ f(l,r)= \begin{cases} (r-l+1)+f(l,m_{l,r ...
- 前缀和:CodeForces 932B Recursive Queries
Description Let us define two functions f and g on positive integer numbers. You need to process Q q ...
- Codeforces 1117G Recursive Queries [线段树]
Codeforces 洛谷:咕咕咕 思路 设\(L_i,R_i\)为\(i\)左右第一个大于它的位置. 对于每一个询问\(l,r\),考虑区间每一个位置的贡献就是\(\min(r,R_i-1)-\ma ...
- 前缀和的应用 CodeForces - 932B Recursive Queries
题目链接: https://vjudge.net/problem/1377985/origin 题目大意就是要你把一个数字拆开,然后相乘. 要求得数要小于9,否则递归下去. 这里用到一个递归函数: i ...
- Recursive Queries CodeForces - 1117G (线段树)
题面: 刚开始想复杂了, 还以为是个笛卡尔树.... 实际上我们发现, 对于询问(l,r)每个点的贡献是$min(r,R[i])-max(l,L[i])+1$ 数据范围比较大在线树套树的话明显过不了, ...
- B. Recursive Queries 打表
Code: #include<cstdio> #include<iostream> #include<algorithm> #include<cstring& ...
随机推荐
- Spring配置hibernate读取实体类映射mappingResources,annotatedClasses,packagesToScan
转自:https://blog.csdn.net/chendc201/article/details/16886545 这两个是有本质区别的,光看名字也能看出来 mappingResources用于指 ...
- java代码调用数据库存储过程
由于前边有写java代码调用数据库,感觉应该把java调用存储过程也写一下,所以笔者补充该篇! package testSpring; import java.sql.CallableStatemen ...
- 如何实现1080P延迟低于500ms的实时超清直播传输技术<转>
转载地址:http://www.yunweipai.com/archives/9037.html 最近由于公司业务关系,需要一个在公网上能实时互动超清视频的架构和技术方案.众所周知,视频直播用 CDN ...
- 记一次完整的android源码截屏事件的捕获<标记砖>
http://blog.csdn.net/buptgshengod/article/details/19911909?utm_source=tuicool&utm_medium=referra ...
- [patl2-001]紧急救援
解题关键:最短路的变形. 1.按顶点存储,$O(n^2)$ #include<cstdio> #include<cstring> #include<algorithm&g ...
- js面试题知识点全解(一原型和原型链)
1.如何准确判断一个变量是数组类型2.写一个原型链继承的例子3.描述new一个对象的过程4.zepto(或其他框架)源码中如何使用原型链知识点:1.构造函数2.构造函数-扩展3.原型规则和示例4.原型 ...
- winform 打印
pageSetupDialog 打印设置,和对话框控件差不多的套路,把控件拖到窗口中后,会在下方显示, 然后在制作的菜单中找到打印设置,双击进入点击事件写代码 按照之前的套路, DialogResul ...
- git在eclipse中的配置 完整版 转载
http://www.cnblogs.com/zhxiaomiao/archive/2013/05/16/3081148.html
- input标签name、value与id属性
id是唯一标识符,不允许有重复值可以通过它的值来获得对应的html标签对象.相当于人的身份证具有唯一性 name:控件的名字,一个控件是否设置它的 name 属性是不会影响到这个网页的功能实现的.但是 ...
- Android 之 信息通知栏消息Notification
Notification是安卓手机顶部的消息提示 这里我们分别设置两个按钮,来实现顶部消息的发送和取消 功能实现 首先要在主Activity中设置一个通知控制类 NotificationManager ...