首页 > 代码库 > HDU 5172 GTY's gay friends (线段树)

HDU 5172 GTY's gay friends (线段树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5172

 

题意:

  给你一个n个数的数组,m次询问,询问在[L, R] 这个区间里面有没有 [1, R-L+1] 的数。

题解:

  判断有没有 1 ~ R-L+1 其实就是判断这一段区间和是不是等于 (R-L+1)*(R-L+1+1)/ 2 。

  当然还有就是每一个数只能出现1次。

  这个问题我们应该怎么解决呢。

  我们可以记录第i个数x 的前一个x出现的位置。如果x的前一个x也出现在[L, R]里面,那么这一段区间就不是1~R-L+1 的全排列。

  所以我们可以O(n) 处理位置为i 的数x 的前一个数的位置 pre[i] 

  用线段树维护这个pre[i] 的区间最大值。在[L, R] 这个区间的pre[i] 的最大值如果在[L, R] , 就NO。

 

  

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 typedef unsigned long long uLL;
15 #define ms(a, b) memset(a, b, sizeof(a))
16 #define rep(a, b) for(int a = 0;a<b;a++)
17 #define rep1(a, b) for(int a = 1;a<=b;a++)
18 #define pb push_back
19 #define mp make_pair
20 #define eps 0.0000000001
21 #define IOS ios::sync_with_stdio(0);cin.tie(0);
22 const LL INF = 0x3f3f3f3f3f3f3f3f;
23 const int inf = 0x3f3f3f3f;
24 const int mod = 1e9+7;
25 const int maxn = 1000000+10;
26 int n, m, x, l, r;
27 int pre[maxn], now[maxn];
28 LL sum[maxn];
29 int maxv[4*maxn];
30 int query(int ql, int qr, int o, int L, int R)
31 {
32     int M = (L+R)>>1;
33     int ans = -1;
34     if(ql <= L && R <= qr)  return maxv[o];
35     if(ql <= M) ans = max(ans, query(ql, qr, o*2, L, M));
36     if(M < qr)  ans = max(ans, query(ql, qr, o*2+1, M+1, R));
37     return ans;
38 }
39 void update(int o, int L, int R)
40 {
41     if(L==R){
42         maxv[o] = pre[L];
43         return;
44     }
45     int M = (L+R)>>1;
46     update(o*2, L, M);
47     update(o*2+1, M+1, R);
48     maxv[o] = max(maxv[o*2], maxv[o*2+1]);
49 }
50 void solve()
51 {
52     ms(now, 0);sum[0] = 0;
53     for(int i = 1;i<=n;i++){
54         scanf("%d", &x);
55         sum[i] = sum[i-1] + 1LL*x;
56         pre[i] = now[x];
57         now[x] = i;
58     }
59     update(1,1,n);
60     while(m--){
61         scanf("%d%d",&l, &r);
62         LL len = 1LL*(r-l+1);
63         if(sum[r]-sum[l-1] != len*(len+1)/2){
64             printf("NO\n");continue;
65         }
66         int Max = query(l, r, 1, 1, n);
67         if(Max<l){
68             printf("YES\n");
69         }
70         else{
71             printf("NO\n");
72         }
73     }
74 }
75 int main() {
76 #ifdef LOCAL
77     freopen("input.txt", "r", stdin);
78 //        freopen("output.txt", "w", stdout);
79 #endif
80 //    IOS
81     while(~scanf("%d%d", &n, &m))
82         solve();
83     return 0;
84 }
View Code

 

HDU 5172 GTY's gay friends (线段树)