1. 程式人生 > >HDU 5172 GTY's gay friends (線段樹)

HDU 5172 GTY's gay friends (線段樹)

ace tac 分享 log 沒有 http inf hdu algorithm

題目鏈接: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 (線段樹)