您的位置:首页 > 其它

bzoj 4491: 我也不知道题目名字是什么(线段树区间和并)

2017-07-19 23:18 267 查看

4491: 我知道题目名字是什么

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 347  Solved: 196

[Submit][Status][Discuss]

Description

给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串

Input

第一行n,表示A数组有多少元素

接下来一行为n个整数A[i]

接下来一个整数Q,表示询问数量

接下来Q行,每行2个整数l,r

Output

对于每个询问,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串

Sample Input

9

1 2 3 4 5 6 5 4 3

5

1 6

1 7

2 7

1 9

5 9

Sample Output

6

6

5

6

4

很简单的区间和并

可以先处理一下,比如求最长上升子串,如果a[i]<a[i+1],那么a[i]=1,否则a[i]=0

最后题目就成了求区间内最长的全1子串

最长下降子串同理

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef struct
{
int x, y;
int len;
}Tree;
Tree Atre[222222], Btre[222222];
int k[55555], a[55555], b[55555];
void Create(int l, int r, int x)
{
int m;
if(l==r)
{
if(a[l]==1) Atre[x].x = Atre[x].y = Atre[x].len = 1;
else Atre[x].x = Atre[x].y = Atre[x].len = 0;
if(b[l]==1) Btre[x].x = Btre[x].y = Btre[x].len = 1;
else Btre[x].x = Btre[x].y = Btre[x].len = 0;
return;
}
m = (l+r)/2;
Create(l, m, x*2);
Create(m+1, r, x*2+1);
if(Atre[x*2].x==m-l+1) Atre[x].x = Atre[x*2+1].x+m-l+1;
else Atre[x].x = Atre[x*2].x;
if(Atre[x*2+1].y==r-m) Atre[x].y = Atre[x*2].y+r-m;
else Atre[x].y = Atre[x*2+1].y;
Atre[x].len = max(Atre[x*2].y+Atre[x*2+1].x, max(Atre[x*2].len, Atre[x*2+1].len));

if(Btre[x*2].x==m-l+1) Btre[x].x = Btre[x*2+1].x+m-l+1;
else Btre[x].x = Btre[x*2].x;
if(Btre[x*2+1].y==r-m) Btre[x].y = Btre[x*2].y+r-m;
else Btre[x].y = Btre[x*2+1].y;
Btre[x].len = max(Btre[x*2].y+Btre[x*2+1].x, max(Btre[x*2].len, Btre[x*2+1].len));
}
int QueryA(int l, int r, int x, int c, int d)
{
int bet, m;
if(l>=c && r<=d)
return Atre[x].len;
m = (l+r)/2;
if(d<=m)
return QueryA(l, m, x*2, c, d);
else if(c>=m+1)
return QueryA(m+1, r, x*2+1, c, d);
else
{
bet = max(QueryA(l, m, x*2, c, d), QueryA(m+1, r, x*2+1, c, d));
bet = max(bet, min(Atre[x*2].y, m-c+1)+min(Atre[x*2+1].x, d-m));
}
return bet;
}
int QueryB(int l, int r, int x, int c, int d)
{
int bet, m;
if(l>=c && r<=d)
return Btre[x].len;
m = (l+r)/2;
if(d<=m)
return QueryB(l, m, x*2, c, d);
else if(c>=m+1)
return QueryB(m+1, r, x*2+1, c, d);
else
{
bet = max(QueryB(l, m, x*2, c, d), QueryB(m+1, r, x*2+1, c, d));
bet = max(bet, min(Btre[x*2].y, m-c+1)+min(Btre[x*2+1].x, d-m));
}
return bet;
}
int main(void)
{
int n, i, q, c, d;
while(scanf("%d", &n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d", &k[i]);
for(i=1;i<=n-1;i++)
{
if(k[i]<=k[i+1]) a[i] = 1;
else a[i] = 0;
if(k[i]>=k[i+1]) b[i] = 1;
else b[i] = 0;
}
Create(1, n-1, 1);
scanf("%d", &q);
while(q--)
{
scanf("%d%d", &c, &d);
if(c>d) swap(c, d);
if(c==d)
printf("1\n");
else
printf("%d\n", max(QueryA(1, n-1, 1, c, d-1), QueryB(1, n-1, 1, c, d-1))+1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: