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& ...
随机推荐
- ajax补充FormData
一.回顾上节知识点 1.什么是json字符串? 轻量级的数据交换格式 2.定时器:关于setTimeout setTimeout(foo,3000) # 3000表示3秒,foo表示一个函数,3秒后 ...
- Delphi XE2 新控件 布局Panel TGridPanel TFlowPanel
Delphi XE2 新控件 Firemonkey 布局Panel Windows平台VCl TGridPanel TFlowPanel FMX 跨平台 TLayout TGridLayout TFl ...
- git clone 某一特定分支<转>
网上搜索自己想要的答案,往往会搜大一大堆感觉没用的,或者看不懂的东西, 最好终于找到了想要答案,特记录一下: ============================================= ...
- 用JS,求斐波那契数列第n项的值
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- sleep()和usleep()
函数名: sleep头文件: #include <windows.h> // 在VC中使用带上头文件 #include <unistd.h> // 在gcc编译 ...
- java中下面这些引入都代表什么意思啊?
import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.sql.*; import java.uti ...
- python3-while与continue
# Auther: Aaron Fan #要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可使用continue#执行continue语句,让python忽略余下的代码 #只打印1到10之间 ...
- DIY的RPM包怎么签名呢 How to sign your custom RPM package with GPG key
https://gist.github.com/fernandoaleman/1376720 How to sign your custom RPM package with GPG key 这是文 ...
- MySQL中的时间问题
MySQL 获得当前日期时间 函数 获得当前日期+时间(date + time)函数:now() mysql> select now(); +---------------------+ | n ...
- 关于LIst Set Map 异常的知识点---我的笔记
今天新的内容1.List接口2.Set接口3.Map集合4.异常==================================================================== ...