题意:给定一个序列,定义[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. 第十二章 Jetty的工作原理解析(待续)

    Jetty的基本架构 Jetty的启动过程 接受请求 处理请求 与JBoss集成 与Tomcat的比较

  2. myeclipse 10破解

    因为笔者的电脑是刚买不久,忘记先给电脑分区,等软年安装差不多了才发现忘记分区,所以就备份了数据,然后分区,结果分区过程中没有异常发生,就没用备用数据,就用分过区的原数据,当时还以为没问题,结果打开my ...

  3. Git中远程仓库的使用

    1.查看当前的远程库 要查看当前配置有哪些远程仓库,可以用 git remote 命令,它会列出每个远程库的简短名字.在克隆完某个项目后,至少可以看到一个名为 origin 的远程库,Git 默认使用 ...

  4. Anaconda 安装教程(Win10环境) Tensorflow安装

    序 Python易用,但用好却不易,其中比较头疼的就是包管理和Python不同版本的问题,特别是当你使用Windows的时候.为了解决这些问题,有不少发行版的Python,比如WinPython.An ...

  5. 错误信息:"OraOLEDB.Oracle" 返回了消息 "ORA-12154: TNS: 无法解析指定的连接标识符

    错误信息:"OraOLEDB.Oracle" 返回了消息 "ORA-12154: TNS: 无法解析指定的连接标识符 链接服务器"NC"的 OLE D ...

  6. PLM数据库迁移注意事项

    需求: PLM应用程序与数据库是存放在同一台服务器上,现需要将数据库迁移到数据库服务器10.10.1.10中. 10.10.1.10中安装了三个实例,MSSQLSERVER.MSSQLSERVER_P ...

  7. TCP UDP HTTP 的关系和区别

    TCP UDP HTTP 三者的关系: TCP/IP是个协议组,可分为四个层次:网络接口层.网络层.传输层和应用层. 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 在传 ...

  8. SpringJdbc 【springjdbc的使用方法】

    1 什么是springjdbc spring对jdbc的封装 2 使用SpringJdbc的编程步骤 2.1 导包 spring-jdbc : springjdbc的包 mysql : MySQL的驱 ...

  9. C++使用标准库的栈和队列

    转自http://blog.csdn.net/zhy_cheng/article/details/8090346 使用标准库的栈和队列时,先包含相关的头文件 #include<stack> ...

  10. Zbar 大图像分析

    博客转载自:https://blog.csdn.net/sunflower_boy/article/details/50429252 为了减少处理时间,可以设定更大的扫描间距,减少不必要的解码类型,去 ...