bzoj4491 我也不知道题目名字是什么

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
//样例解释
五个询问分别对应
[1,6][1,6][2,6][1,6][6,9]

HINT

N,Q<=50000

正解:线段树。

线段树傻逼题,维护$8$个标记即可。

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set>
13 #define N (100010)
14 #define ls (x<<1)
15 #define rs (x<<1|1)
16 #define il inline
17 #define RG register
18 #define ll long long
19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
20 
21 using namespace std;
22 
23 struct data{ int mx,mn,lmx,rmx,lmn,rmn,L,R; }t[4*N];
24 
25 int a[N],n,Q;
26 
27 il int gi(){
28     RG int x=0,q=1; RG char ch=getchar();
29     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
30     if (ch=='-') q=-1,ch=getchar();
31     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
32     return q*x;
33 }
34 
35 il void pushup(RG data &x,RG data l,RG data r,RG int h,RG int t,RG int mid){
36     x.mx=max(l.mx,r.mx); if (l.R<=r.L) x.mx=max(x.mx,l.rmx+r.lmx);
37     x.mn=max(l.mn,r.mn); if (l.R>=r.L) x.mn=max(x.mn,l.rmn+r.lmn);
38     x.lmx=(l.mx==mid-h+1 && l.R<=r.L) ? l.mx+r.lmx : l.lmx;
39     x.rmx=(r.mx==t-mid && l.R<=r.L) ? r.mx+l.rmx : r.rmx;
40     x.lmn=(l.mn==mid-h+1 && l.R>=r.L) ? l.mn+r.lmn : l.lmn;
41     x.rmn=(r.mn==t-mid && l.R>=r.L) ? r.mn+l.rmn : r.rmn;
42     x.L=l.L,x.R=r.R; return;
43 }
44 
45 il void build(RG int x,RG int l,RG int r){
46     if (l==r){
47     t[x].mx=t[x].mn=t[x].lmx=t[x].rmx=t[x].lmn=t[x].rmn=1;
48     t[x].L=t[x].R=a[l]; return;
49     }
50     RG int mid=(l+r)>>1; build(ls,l,mid),build(rs,mid+1,r);
51     pushup(t[x],t[ls],t[rs],l,r,mid); return;
52 }
53 
54 il data query(RG int x,RG int l,RG int r,RG int xl,RG int xr){
55     if (xl<=l && r<=xr) return t[x]; RG int mid=(l+r)>>1;
56     if (xr<=mid) return query(ls,l,mid,xl,xr);
57     else if (xl>mid) return query(rs,mid+1,r,xl,xr);
58     else{
59     RG data res;
60     pushup(res,query(ls,l,mid,xl,mid),query(rs,mid+1,r,mid+1,xr),xl,xr,mid);
61     return res;
62     }
63 }
64 
65 il int find(RG int l,RG int r){
66     RG data res=query(1,1,n,l,r);
67     return max(res.mx,res.mn);
68 }
69 
70 il void work(){
71     n=gi(); for (RG int i=1;i<=n;++i) a[i]=gi();
72     build(1,1,n); Q=gi();
73     for (RG int i=1,l,r;i<=Q;++i)
74     l=gi(),r=gi(),printf("%d
",find(l,r));
75     return;
76 }
77 
78 int main(){
79     File("substring");
80     work();
81     return 0;
82 }
原文地址:https://www.cnblogs.com/wfj2048/p/7112869.html