4491: 我知道题目名字是什么
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 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;
}