题意:给定一个序列,定义[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. 数据库连接池在Tomcat中的几种配置方法

    数据库连接是一种关键的有限的昂贵的资源,这在多用户网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标,数据库连接池正是针对这个问题提出的. ...

  2. 云服务利用Auto Scaling节省30%成本

    公有云提供了很多免费的高级功能,很多中小用户以为自己用不上.实际上稍微研究一下,就能享受很多便利和节省不少成本. 本方案就是利用弹性伸缩(auto-scaling)减少服务器成本,几乎适合所有集群式部 ...

  3. SqlServer——存储过程(未完工)

    http://www.cnblogs.com/blsong/archive/2009/11/30/1613534.html http://blog.csdn.net/lenotang/article/ ...

  4. 使用GSON来生成JSON数据

    第二种方法: 当不需要显示某个属性时,在不需要显示出的属性前加transient关键字即可满足 使用gson来解析 使用gson解析 带日期转换 集合类解析:gson中的数组与java中集合类都是对应 ...

  5. 读书笔记<深入理解JVM>01 关于OutOfMemoryError 堆空间的溢出

    代码片段如下: package com.gosaint.shiro; import java.util.ArrayList; import java.util.List; public class H ...

  6. 4-5 父节点watcher事件

    三种方式设置watcher:ls.stat.get

  7. intellij idea 在执行maven的操作 install等会出现中文乱码?其他程序打印正常?

    之前一直碰到过这个问题,也没在意,因为那个中文对我来说用处不大,今天看着务必难受,一定把他给解决了,查了一下,找到了解决方法,如下: 首先打开你的设置. Setting->maven->r ...

  8. 生产者与消费者-1:1-基于list

    一个生产者/一个消费者: /** * 生产者 */ public class P { private MyStack stack; public P(MyStack stack) { this.sta ...

  9. keystone组件

    引:  什么是keystone    为何要有keystone     keystone的功能     keystone概念详解     keystone与openstack其他组件关系      k ...

  10. 安装thrift时,注意openssl参数

    在安装基于openssl-1.0.1c的thrift-0.9.0时,正常使用--with-openssl在configure时会出错,报"Error: libcrypto required. ...