题目大意:给你两个长度为n的数组a, b,问你有多少个问你有多少个区间满足

a中最大值等于b中最小值。

思路:我本来的想法是用单调栈求出每个点的管辖区间,然后问题就变成了巨麻烦的线段覆盖问题,就爆炸写了

一晚上假算法。正解就是枚举一个端点,然后二分找右端点的区间,因为满足一个很神奇的单调性,然后st表维护

一下区间最值就好了。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int> using namespace std; const int N = 2e5 + ;
const int M = 1e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ; int n, a[N], b[N], bin[], Log[N], mx[][N], mn[][N]; void calRmq() {
bin[] = ; Log[] = -;
for(int i = ; i < ; i++) bin[i] = bin[i - ] * ;
for(int i = ; i < N; i++) Log[i] = Log[i / ] + ; for(int i = ; i <= n; i++) mx[][i] = a[i];
for(int i = ; i <= n; i++) mn[][i] = b[i]; for(int i = ; i <= Log[n]; i++) {
for(int j = ; j <= n; j++) {
if(j + bin[i] - <= n) {
mn[i][j] = min(mn[i - ][j], mn[i - ][j + bin[i - ]]);
mx[i][j] = max(mx[i - ][j], mx[i - ][j + bin[i - ]]);
}
}
}
} int getVal(int x, int y, int op) {
int t = Log[y - x + ];
if(op) return max(mx[t][x], mx[t][y - bin[t] + ]);
return min(mn[t][x], mn[t][y - bin[t] + ]);
} int main(){
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
}
for(int i = ; i <= n; i++) {
scanf("%d", &b[i]);
} calRmq(); LL ans = ;
for(int i = ; i <= n; i++) {
int l = i, r = n, mid, ret1 = -, ret2 = -;
while(l <= r) {
mid = l + r >> ;
int valMin = getVal(i, mid, );
int valMx = getVal(i, mid, );
if(valMin > valMx) l = mid + ;
else if(valMin < valMx) r = mid - ;
else ret1 = mid, r = mid - ;
} l = i, r = n;
while(l <= r) {
mid = l + r >> ;
int valMin = getVal(i, mid, );
int valMx = getVal(i, mid, );
if(valMin > valMx) l = mid + ;
else if(valMin < valMx) r = mid - ;
else ret2 = mid, l = mid + ;
} if(ret1 != -) {
ans += ret2 - ret1 + ;
}
} printf("%lld\n", ans);
return ;
} /*
*/
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int> using namespace std; const int N = 1e5;
const int M = 1e6 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +; int mm[N];
struct ST
{
int dp[N][],ty;
void build(int n,int b[],int _ty)
{
ty=_ty;
for(int i=;i<=n;i++)
dp[i][]=ty*b[i];
for(int j=;j<=mm[n];j++)
for(int i=;i+(<<j)-<=n;i++)
dp[i][j]=max(dp[i][j-],dp[i+(<<(j-))][j-]);
}
int query(int x,int y)
{
int k=mm[y-x+];
return ty*max(dp[x][k],dp[y-(<<k)+][k]);
}
}rmq; int a[N];
int main() { for(int i=-(mm[]=-);i<N;i++)
mm[i]=mm[i-]+((i&(i-))==); int n; scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
}
rmq.build(n, a, ); while() {
int x, y; scanf("%d%d", &x, &y);
cout << rmq.query(x, y) << endl;
}
return ;
}

还有一个很神奇的st表

Codeforces Round #361 (Div. 2) D - Friends and Subsequences的更多相关文章

  1. Codeforces Round #361 (Div. 2) D. Friends and Subsequences 二分

    D. Friends and Subsequences 题目连接: http://www.codeforces.com/contest/689/problem/D Description Mike a ...

  2. Codeforces Round #361 (Div. 2) C.NP-Hard Problem

    题目连接:http://codeforces.com/contest/688/problem/C 题意:给你一些边,问你能否构成一个二分图 题解:二分图:二分图又称作二部图,是图论中的一种特殊模型. ...

  3. Codeforces Round #361 (Div. 2) E. Mike and Geometry Problem 离散化 排列组合

    E. Mike and Geometry Problem 题目连接: http://www.codeforces.com/contest/689/problem/E Description Mike ...

  4. Codeforces Round #361 (Div. 2) C. Mike and Chocolate Thieves 二分

    C. Mike and Chocolate Thieves 题目连接: http://www.codeforces.com/contest/689/problem/C Description Bad ...

  5. Codeforces Round #361 (Div. 2) B. Mike and Shortcuts bfs

    B. Mike and Shortcuts 题目连接: http://www.codeforces.com/contest/689/problem/B Description Recently, Mi ...

  6. Codeforces Round #361 (Div. 2) A. Mike and Cellphone 水题

    A. Mike and Cellphone 题目连接: http://www.codeforces.com/contest/689/problem/A Description While swimmi ...

  7. Codeforces Round #361 (Div. 2) E. Mike and Geometry Problem 【逆元求组合数 && 离散化】

    任意门:http://codeforces.com/contest/689/problem/E E. Mike and Geometry Problem time limit per test 3 s ...

  8. Codeforces Round #361 (Div. 2) D

    D - Friends and Subsequences Description Mike and !Mike are old childhood rivals, they are opposite ...

  9. Codeforces Round #361 (Div. 2) C

    C - Mike and Chocolate Thieves Description Bad news came to Mike's village, some thieves stole a bun ...

随机推荐

  1. lsof显示打开的文件

    lsof `which httpd` //那个进程在使用apache的可执行文件 lsof /etc/passwd //那个进程在占用/etc/passwd lsof /dev/hda6 //那个进程 ...

  2. python基础--文件操作实现全文或单行替换

    python修改文件时,使用w模式会将原本的文件清空/覆盖.可以先用读(r)的方式打开,写到内存中,然后再用写(w)的方式打开. 替换文本中的taste 为 tasting Yesterday whe ...

  3. Splay 区间操作(二)

    首先基本操作如下: 删除第rank个点 void Remove(int id){//删除第rank个点 rank++; int x = find(root, rank - 1); splay(x, 0 ...

  4. 前端PHP入门-021-重点日期函数之日期验证函数

    checkdate可以判断一个输出的日期是否有效. 在实际的工作中,我们需要经常用于检测常用于用户提交表单的数据验证. 函数的语法格式如下: bool checkdate ( int month,in ...

  5. 前端PHP入门-016-静态变量

    如果我想知道函数被调用了多少次怎么办?在没有学习静态变量的时候,我们没有好的办法来解决. 静态变量的特点是:声明一个静态变量,第二次调用函数的时候,静态变量不会再初始化变量,会在原值的基础上读取执行. ...

  6. TabLayout 使用方法 (基础)

    此为布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:a ...

  7. ③ 设计模式的艺术-09.组合(Composite)模式

    使用组合模式的场景 类图当中有三个类,一个是Component(节点的统一接口),它的目的是为了统一节点的操作.接下来的两个实现类,一个则是非叶子节点(Composite),它可以有子节点.另外一个则 ...

  8. Intellij IDEA 快捷键整理(转)

    Ctrl+Shift + Enter,语句完成 “!”,否定完成,输入表达式时按 “!”键 Ctrl+E,最近的文件 Ctrl+Shift+E,最近更改的文件 Shift+Click,可以关闭文件 C ...

  9. 如何编写高质量的 jQuery 代码?

    想必大家对于jQuery这个最流行的javascript类库都不陌生,而且只要是前端开发人员肯定或多或少的使用或者接触过,在今天的这篇文章中,我们将介绍一些书写高质量jQuery代码的原则,我们不单单 ...

  10. 天梯赛L2-008 最长对称子串 (字符串处理)

    对给定的字符串,本题要求你输出最长对称子串的长度.例如,给定"Is PAT&TAP symmetric?",最长对称子串为"s PAT&TAP s&quo ...