【BZOJ4491】我也不知道题目名字是什么 [线段树]

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

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 315  Solved: 173
[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

HINT

  N,Q<=50000

Solution

  直接上线段树,记录一下一个区间内:左边最长,右边最长,整体最优。再分一下不下降不上升即可。

Code

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cmath>
 8 #include<queue>
 9 using namespace std;
10
11 const int ONE = 500005;
12 const int INF = 2147483640;
13
14 int n,Q;
15 int x,y;
16 int a[ONE];
17
18 struct power
19 {
20         int len;
21         int Lval, Rval;
22         int Lup,Ldn, Rup,Rdn;
23         int Maxup, Maxdn;
24
25         friend power operator +(power a, power b)
26         {
27             power A;
28             A.len = a.len + b.len;
29             A.Lval = a.Lval;    A.Rval = b.Rval;
30
31             A.Lup = a.Lup;    if(a.Lup == a.len && a.Rval <= b.Lval) A.Lup += b.Lup;
32             A.Ldn = a.Ldn;    if(a.Ldn == a.len && a.Rval >= b.Lval) A.Ldn += b.Ldn;
33
34             A.Rup = b.Rup;    if(b.Rup == b.len && a.Rval <= b.Lval) A.Rup += a.Rup;
35             A.Rdn = b.Rdn;    if(b.Rdn == b.len && a.Rval >= b.Lval) A.Rdn += a.Rdn;
36
37             A.Maxup = max(a.Maxup, b.Maxup);
38             A.Maxdn = max(a.Maxdn, b.Maxdn);
39
40             if(a.Rval <= b.Lval) A.Maxup = max(A.Maxup, a.Rup+b.Lup);
41             if(a.Rval >= b.Lval) A.Maxdn = max(A.Maxdn, a.Rdn+b.Ldn);
42
43             return A;
44         }
45 }Node[ONE];
46
47 int get()
48 {
49         int res=1,Q=1;char c;
50         while( (c=getchar())<48 || c>57 )
51         if(c==‘-‘)Q=-1;
52         res=c-48;
53         while( (c=getchar())>=48 && c<=57 )
54         res=res*10+c-48;
55         return res*Q;
56 }
57
58 void Build(int i,int l,int r)
59 {
60         if(l == r)
61         {
62             Node[i].Lval = Node[i].Rval = a[l];
63             Node[i].len = 1;
64             Node[i].Lup = Node[i].Rup = Node[i].Ldn = Node[i].Rdn = 1;
65             Node[i].Maxup = Node[i].Maxdn = 1;
66             return;
67         }
68
69         int mid = l+r>>1;
70         Build(i<<1, l,mid);    Build(i<<1|1, mid+1,r);
71         Node[i] = Node[i<<1] + Node[i<<1|1];
72 }
73
74 power Query(int i,int l,int r,int L,int R)
75 {
76         if(L==l && r==R) return Node[i];
77         int mid = l+r>>1;
78         if(mid+1 > R) return Query(i<<1, l,mid,L,R);
79         else if(L > mid) return Query(i<<1|1, mid+1,r,L,R);
80         else return Query(i<<1, l,mid,L,mid) + Query(i<<1|1, mid+1,r,mid+1,R);
81 }
82
83 int main()
84 {
85         n = get();
86         for(int i=1; i<=n; i++) a[i] = get();
87         Build(1,1,n);
88
89         Q = get();
90         while(Q--)
91         {
92             x = get();    y = get();
93             power res = Query(1,1,n,x,y);
94             printf("%d\n", max(res.Maxup, res.Maxdn) );
95         }
96 }

时间: 2024-12-24 18:16:53

【BZOJ4491】我也不知道题目名字是什么 [线段树]的相关文章

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

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

4491: 我也不知道题目名字是什么 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 278  Solved: 154[Submit][Status][Discuss] Description 给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串 Input 第一行n,表示A数组有多少元素接下来一行为n个整数A[i]接下来一个整数Q,表示询问数量接下来Q行,每行2个整数l,r Output 对于每个询问,

BZOJ 4491: 我也不知道题目名字是什么 RMQ

4491: 我也不知道题目名字是什么 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 317  Solved: 174[Submit][Status][Discuss] Description 给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串 Input 第一行n,表示A数组有多少元素 接下来一行为n个整数A[i] 接下来一个整数Q,表示询问数量 接下来Q行,每行2个整数l,r Output 对于每个

HDOJ 题目4325 Flowers(线段树+离散化)

Flowers Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2493    Accepted Submission(s): 1235 Problem Description As is known to all, the blooming time and duration varies between different kind

HDOJ 题目4339 Query(线段树,单点更新)

Query Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2859    Accepted Submission(s): 925 Problem Description You are given two strings s1[0..l1], s2[0..l2] and Q - number of queries. Your ta

HDOJ 题目2795 Billboard(线段树单点更新)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12813    Accepted Submission(s): 5579 Problem Description At the entrance to the university, there is a huge rectangular billboard of

HDOJ 题目3308 LCIS(线段树,区间查询,区间合并)

LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5319    Accepted Submission(s): 2361 Problem Description Given n integers. You have two operations: U A B: replace the Ath number by B. (ind

POJ 题目3667 Hotel(线段树,区间更新查询,求连续区间)

Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13805   Accepted: 5996 Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie

hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum【线段树】

https://hihocoder.com/problemset/problem/1586 线段树操作,原来题并不难..... 要求乘积最小只要求区间内最大值.最小值和绝对值小的数,再判断min,max正负就行了. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define lson l,