题意:给定一个序列,定义[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的更多相关文章

  1. sql script: Graphs, Trees, Hierarchies and Recursive Queries

    --------------------------------------------------------------------- -- Inside Microsoft SQL Server ...

  2. sql server: Graphs, Trees, Hierarchies and Recursive Queries

    --------------------------------------------------------------------- -- Chapter 09 - Graphs, Trees, ...

  3. Codeforces 932.B Recursive Queries

    B. Recursive Queries time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  4. 笔记-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 ...

  5. 前缀和:CodeForces 932B Recursive Queries

    Description Let us define two functions f and g on positive integer numbers. You need to process Q q ...

  6. Codeforces 1117G Recursive Queries [线段树]

    Codeforces 洛谷:咕咕咕 思路 设\(L_i,R_i\)为\(i\)左右第一个大于它的位置. 对于每一个询问\(l,r\),考虑区间每一个位置的贡献就是\(\min(r,R_i-1)-\ma ...

  7. 前缀和的应用 CodeForces - 932B Recursive Queries

    题目链接: https://vjudge.net/problem/1377985/origin 题目大意就是要你把一个数字拆开,然后相乘. 要求得数要小于9,否则递归下去. 这里用到一个递归函数: i ...

  8. Recursive Queries CodeForces - 1117G (线段树)

    题面: 刚开始想复杂了, 还以为是个笛卡尔树.... 实际上我们发现, 对于询问(l,r)每个点的贡献是$min(r,R[i])-max(l,L[i])+1$ 数据范围比较大在线树套树的话明显过不了, ...

  9. B. Recursive Queries 打表

    Code: #include<cstdio> #include<iostream> #include<algorithm> #include<cstring& ...

随机推荐

  1. Spring配置hibernate读取实体类映射mappingResources,annotatedClasses,packagesToScan

    转自:https://blog.csdn.net/chendc201/article/details/16886545 这两个是有本质区别的,光看名字也能看出来 mappingResources用于指 ...

  2. java代码调用数据库存储过程

    由于前边有写java代码调用数据库,感觉应该把java调用存储过程也写一下,所以笔者补充该篇! package testSpring; import java.sql.CallableStatemen ...

  3. 如何实现1080P延迟低于500ms的实时超清直播传输技术<转>

    转载地址:http://www.yunweipai.com/archives/9037.html 最近由于公司业务关系,需要一个在公网上能实时互动超清视频的架构和技术方案.众所周知,视频直播用 CDN ...

  4. 记一次完整的android源码截屏事件的捕获<标记砖>

    http://blog.csdn.net/buptgshengod/article/details/19911909?utm_source=tuicool&utm_medium=referra ...

  5. [patl2-001]紧急救援

    解题关键:最短路的变形. 1.按顶点存储,$O(n^2)$ #include<cstdio> #include<cstring> #include<algorithm&g ...

  6. js面试题知识点全解(一原型和原型链)

    1.如何准确判断一个变量是数组类型2.写一个原型链继承的例子3.描述new一个对象的过程4.zepto(或其他框架)源码中如何使用原型链知识点:1.构造函数2.构造函数-扩展3.原型规则和示例4.原型 ...

  7. winform 打印

    pageSetupDialog 打印设置,和对话框控件差不多的套路,把控件拖到窗口中后,会在下方显示, 然后在制作的菜单中找到打印设置,双击进入点击事件写代码 按照之前的套路, DialogResul ...

  8. git在eclipse中的配置 完整版 转载

    http://www.cnblogs.com/zhxiaomiao/archive/2013/05/16/3081148.html

  9. input标签name、value与id属性

    id是唯一标识符,不允许有重复值可以通过它的值来获得对应的html标签对象.相当于人的身份证具有唯一性 name:控件的名字,一个控件是否设置它的 name 属性是不会影响到这个网页的功能实现的.但是 ...

  10. Android 之 信息通知栏消息Notification

    Notification是安卓手机顶部的消息提示 这里我们分别设置两个按钮,来实现顶部消息的发送和取消 功能实现 首先要在主Activity中设置一个通知控制类 NotificationManager ...