题目链接: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 }
HDU 5172 GTY's gay friends (线段树)
时间: 2024-12-18 06:43:06