hdu 6406 Taotao Picks Apples problem solution

Problem Description

There is an apple tree in front of Taotao's house. When autumn comes,  n apples on the tree ripen, and Taotao will go to pick these apples.

When Taotao picks apples, Taotao scans these apples from the first one to the last one. If the current apple is the first apple, or it is strictly higher than the previously picked one, then Taotao will pick this apple; otherwise, he will not pick.

Given the heights of these apples h1,h2,,hn, you are required to answer some independent queries. Each query is two integers p,q, which asks the number of apples Taotao would pick, if the height of the p-th apple were q (instead of hp). Can you answer all these queries?
 

 

Input

The first line of input is a single line of integer  T (1T10), the number of test cases.

Each test case begins with a line of two integers n,m (1n,m105), denoting the number of apples and the number of queries. It is then followed by a single line of n integers h1,h2,,hn (1hi109), denoting the heights of the apples. The next m lines give the queries. Each of these m lines contains two integers p (1pn) and q (1q109), as described in the problem statement.
 

 

Output

For each query, display the answer in a single line.
 

 

Sample Input

1 5 3
1 2 3 4 4
1 5
5 5
2 3
 

 

Sample Output

1 5 3

Hint

For the first query, the heights of the apples were 5, 2, 3, 4, 4, so Taotao would only pick the first apple. For the second query, the heights of the apples were 1, 2, 3, 4, 5, so Taotao would pick all these five apples. For the third query, the heights of the apples were 1, 3, 3, 4, 4, so Taotao would pick the first, the second and the fourth apples.
 
 

Solution

To get the title beginning with the prefix and would like to maintain the answer, but there is no clear thinking, and later into chaos. God saw a large segment tree maintenance solution to a problem directly answer simple reason his thoughts

For the tree line, and maximum maintenance intervals increase the length of the interval from left to right (ie the answer), we note that the contribution of a range of answers = answers interval left + right number range in the left interval maximum value on the basis of

For a query query (rt, v) represents the contribution of a number changed after the interval rt v answers before the interval t,

If rt-> maxx <v directly back to 0, the total is less than the maximum interval v , this interval can not contribute answer

Otherwise, if rt-> lson-> maxx> v then just focus on the left section, because the right and this time interval contribution of v uncorrelated, attention then returns the answer should be tr [rt] .cnt-tr [ lson ] .cnt + query (lson, v ), instead of tr [rson] .cnt + query ( lson, v)

The two are not equivalent, because a cnt represents the increase in length of the current interval from left to right, and tr [rson] .cnt only concern is the right range, and overall there is no direct link

Then if TR-> lson-> maxx <= v , this time left no contributions range of answers, but the right zone presence, the right query interval

Is probably the case, the answer is very flexible segment tree maintenance feeling, alas, I can not think of garbage

Posted a probably write code for it after understanding ac

 


 

  1 #include <bits/stdc++.h>
  2 #define lson rt << 1
  3 #define rson rt << 1 | 1
  4 using namespace std;
  5 using ll = long long;
  6 using ull = unsigned long long;
  7 using pa = pair<int, int>;
  8 using ld = long double;
  9 int n, m, k;
 10 const int maxn = 1e5 + 10;
 11 const int mod = 998244353;
 12 int pre[maxn];
 13 template <class T>
 14 inline T read(T &ret)
 15 {
 16     int f = 1;
 17     ret = 0;
 18     char ch = getchar();
 19     while (!isdigit(ch))
 20     {
 21         if (ch == '-')
 22             f = -1;
 23         ch = getchar();
 24     }
 25     while (isdigit(ch))
 26     {
 27         ret = (ret << 1) + (ret << 3) + ch - '0';
 28         ch = getchar();
 29     }
 30     ret *= f;
 31     return ret;
 32 }
 33 template <class T>
 34 inline void write(T n)
 35 {
 36     if (n < 0)
 37     {
 38         putchar('-');
 39         n = -n;
 40     }
 41     if (n >= 10)
 42     {
 43         write(n / 10);
 44     }
 45     putchar(n % 10 + '0');
 46 }
 47 int a[maxn];
 48 struct node
 49 {
 50     int l, r, cnt, maxx;
 51 } tr[maxn << 2];
 52 int query(int rt, int v)
 53 {
 54     int l = tr[rt].l;
 55     int r = tr[rt].r;
 56     if (l == r)
 57         return tr[rt].maxx > v;
 58     if (tr[rt].maxx < v)
 59         return 0;
 60     int mid = l + r >> 1;
 61     if (tr[lson].maxx > v) //Wonder why write tr [rson] .cnt + query ( lson, v) does not answer
 62                             // ah about the interval and the interval is not equal to the big, big interval interval = left + right interval contribution 
63          return TR [RT] .cnt - [LSON] + TR .cnt Query (LSON, V);
 64      the else 
65          return Query (rson, V);
 66  }
 67  void a pushup ( int RT)
 68  {
 69      TR [RT] .maxx = max (TR [LSON ] .maxx, TR [rson] .maxx);
 70      TR [RT] = .cnt TR [LSON] + .cnt Query (rson, TR [LSON] .maxx);
 71 is  }
 72  void Build ( int RT, int L , int r)
 73 {
 74     tr[rt].l = l;
 75     tr[rt].r = r;
 76     if (l == r)
 77     {
 78         tr[rt].cnt = 1;
 79         tr[rt].maxx = a[l];
 80         return;
 81     }
 82     int mid = l + r >> 1;
 83     build(lson, l, mid);
 84     build(rson, mid + 1, r);
 85     pushup(rt);
 86 }
 87 void update(int rt, int L, int v)
 88 {
 89     int l = tr[rt].l;
 90     int r = tr[rt].r;
 91     if (l == r && l == L)
 92     {
 93         tr[rt].maxx = v;
 94         return;
 95     }
 96     int mid = l + r >> 1;
 97     if (L <= mid)
 98         update(lson, L, v);
 99     else
100         update(rson, L, v);
101     pushup(rt);
102 }
103 int main(int argc, char const *argv[])
104 {
105     ios::sync_with_stdio(false);
106     cin.tie(0);
107     cout.tie(0);
108     int t;
109     cin >> t;
110     while (t--)
111     {
112         cin >> n >> m;
113         for (int i = 1; i <= n; i++)
114             cin >> a[i];
115         build(1, 1, n);
116         while (m--)
117         {
118             int p, q;
119             cin >> p >> q;
120             update(1, p, q);
121             cout << tr[1].cnt << "\n";
122             update(1, p, a[p]);
123         }
124     }
125     return 0;
126 }
View Code

 

Guess you like

Origin www.cnblogs.com/mooleetzi/p/11287982.html