题目链接:https://codeforc.es/contest/1156/problem/E

题目大意:

在数组p中可以找到多少个不同的l,r满足

思路:

ST表+并查集。

ST表还是需要的,因为nlongn的预处理就可以O(1)查询。枚举所有的区间也就O(n^2)。

因为是输入固定1-n,所以我可以设一个y数组表示数组p的值所对应的下标。

(习惯输入为x数组)

我们考虑一个区间[l,r]这个区间最大值为i。(这里用ST表可以找到)

[l,r]对答案的贡献为最大值i左边找一个值a,右边找一个值b,满足a+b==i。有多少个不同的a,b对。

我们可以枚举i左右两边长度小的区间。然后在大区间上找。(小区间就可以少枚举点不是吗?最坏左右区间长度一样总共也就nlongn次)。

然后的问题是怎样找快速查找。

我们用并查集。

把大区间的所有值加入在大区间的最大值上。

你一定疑惑这样做还是会超时的啊。

如果在我们得到这个区间对答案的贡献后,把i左右两区间的最大值加在i上就可以完美的解决这个问题了。

我们直接从区间[1,n]开始,向下遍历,稍微注意一下边缘条件就OK啦。

整个就像一个线段树呢。

人太垃圾,ST表直接复制的板子,如有抄袭希望可以交个朋友哈~~

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);
#define int long long
#define N 200100
#define mod 1000000007 int x[N];
int y[N]; int pre[N];
int find(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x,j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void join(int x,int y)
{
int a=find(x);
int b=find(y);
if(a!=b)
{
pre[a]=b;
}
}
void into()
{
for(int i=; i<N; i++)
{
pre[i]=i;
}
} int st[N][]; void init(int n)
{
n++;
for (int i = ; i < n; i++)
st[i][] = x[i]; for (int j = ; ( << j) <= n; j++)
{
for (int i = ; i + ( << j) - < n; i++)
st[i][j] = max(st[i][j - ],st[i + ( << (j - ))][j - ]);
}
} int search(int l, int r)
{
int k = (int)(log((double)(r - l + )) / log(2.0));
return max(st[l][k],st[r - ( << k) + ][k]);
} int Ans;
void dfs(int i,int l,int r)
{
int a=,b=;
if(y[i]>l)
{
a=search(l,y[i]-);
//cout<<i<<" "<<a<<endl;
dfs(a,l,y[i]-);
}
if(y[i]<r)
{
b=search(y[i]+,r);
//cout<<i<<" "<<b<<endl;
dfs(b,y[i]+,r);
} if(r-y[i]<y[i]-l)
{
for(int j=y[i]+; j<=r; j++)
{
if(find(i-x[j])==a)
{
Ans++;
}
}
}
else
{
for(int j=l; j<=y[i]-; j++)
{
if(find(i-x[j])==b)
{
Ans++;
}
}
}
if(a)
join(a,i);
if(b)
join(b,i);
} signed main()
{
IOS;
into(); int n,a;
cin>>n; for(int i=; i<=n; i++)
{
cin>>x[i];
y[x[i]]=i;
} init(n); dfs(n,,n); cout<<Ans; return ;
}

codeforces 1156E Special Segments of Permutation的更多相关文章

  1. Codeforces 1156E Special Segments of Permutation(单调栈)

    可以用单调栈直接维护出ai所能覆盖到的最大的左右范围是什么,然后我们可以用这个范围暴力的去查询这个区间的是否有满足的点对,一个小坑点,要对左右区间的大小进行判断,只需要去枚举距离i最近的一段区间去枚举 ...

  2. Codeforces 1156E Special Segments of Permutation(启发式合并)

    题意: 给一个n的排列,求满足a[l]+a[r]=max(l,r)的(l,r)对数,max(l,r)指的是l到r之间的最大a[p] n<=2e5 思路: 先用单调栈处理出每个点能扩展的l[i], ...

  3. Special Segments of Permutation - CodeForces - 1156E (笛卡尔树上的启发式合并)

    题意 给定一个全排列\(a\). 定义子区间\([l,r]\),当且仅当\(a_l + a_r = Max[l,r]\). 求\(a\)序列中子区间的个数. 题解 笛卡尔树上的启发式合并. \(200 ...

  4. CF1156E Special Segments of Permutation

    思路:笛卡尔树?(好像并不一定要建出来,但是可以更好理解) 提交:2次 错因:没有判左右儿子是否为空来回溯导致它T了 题解: 建出笛卡尔树,考虑如何计算答案: 先预处理每一个值出现的位置 \(pos[ ...

  5. codeforces 895B XK Segments 二分 思维

    codeforces 895B XK Segments 题目大意: 寻找符合要求的\((i,j)\)对,有:\[a_i \le a_j \] 同时存在\(k\),且\(k\)能够被\(x\)整除,\( ...

  6. Codeforces 785 E. Anton and Permutation(分块,树状数组)

    Codeforces 785 E. Anton and Permutation 题目大意:给出n,q.n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询.每次查询给出两个数l,r,要求 ...

  7. CodeForces 219B Special Offer! Super Price 999 Bourles!

    Special Offer! Super Price 999 Bourles! Time Limit:1000MS     Memory Limit:262144KB     64bit IO For ...

  8. CodeForces 691D:Swaps in Permutation(并查集)

    http://codeforces.com/contest/691/problem/D D. Swaps in Permutation   You are given a permutation of ...

  9. codeforces 676A A. Nicholas and Permutation(水题)

    题目链接: A. Nicholas and Permutation time limit per test 1 second memory limit per test 256 megabytes i ...

随机推荐

  1. linux线程的实现(转)

    原文:https://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一 ...

  2. VM10 不能安装VMware tools的解决方法

    当安装VMware tools,提示"正在进行简易安装时,无法手动启动VMware TOOLS安装",把CD-ROM设置成自动检测就可以了.

  3. ajax 请求成功,但是后台feigin请求超时解决方案

    ========后台请求数据时间较长,报feigin超时错误====== fegin报错如下: feign.RetryableException: Read timed out executing P ...

  4. Windows10家庭版的功能中没有Hyper-V的解决方法

    1.在桌面新建记事本 将下面的内容复制到编辑器或者记事本当中 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper ...

  5. Spring、SpringMVC注解方式整合

    1 原理 Web容器在启动的时候,会扫描每个jar包下的META-INF/services/javax.servlet.ServletContainerInitializer文件. 加载META-IN ...

  6. pymysql ,主键, 索引

    目录 一.pymysql模块的使用 1. 安装pymysql 2. 连接MySQL 3. sql注入问题 二.索引 1. 什么是索引 2. 索引有什么用 3. 索引的底层原理 4. 主键 5. MyS ...

  7. JAVA泛型里面各值代表的意义

    Java泛型中的标记符含义:  E - Element (在集合中使用,因为集合中存放的是元素) T - Type(Java 类) K - Key(键) V - Value(值) N - Number ...

  8. WIN 7 的vs2008 试用版评估期结束的解决方法

    1. 在VS2008安装目录下把Setup/setup.sdb文件中的 [Product Key] T2CRQGDKBVW7KJR8C6CKXMW3D 改成 [Product Key] PYHYPWX ...

  9. JavaScript动态创建script标签并执行js代码

    <script> //创建一个script标签 function loadScriptString(code) { var script = document.createElement( ...

  10. luoguP1197 [JSOI2008]星球大战 x

    P1197 [JSOI2008]星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中 ...