[HDU-5172] 单点查询线段树

题意:

给你一个长度为n的数组v[],有m次询问,问你在区间[L,R]中是否包含区间[1,R-L+1]的全部数字,如果是输出YES,否则输出NO

 

题解:

区间[1,R-L+1]与区间[L,R]的长度一样,所以如果输出YES,那么区间[L,R]中的数字就是1到R-L+1数字的全排列形式。那么就判断这个满足下面两点就行

1、区间和等于(R-L+2)*(R-L+1)/2;

2.该段区间内没有重复数字。

 

对于第一点我们只需要用前缀和就可以。

对于第二点,我们可以用lpos[i]表示输入的v[i]这个数字上一次(就是在区间[1,i-1])出现的最大位置,如果之前没有出现过就初始为0.这样的话对于区间内是否有重复数字,我们只需要查找一下下标为[L,R]的这些位置的值lpos[i]的最大值是否大于L,大于的话那么也就意味着这个区间内出现重复值了,就输出NO

 

代码:

 1 #include <iostream>
 2 #include <queue>
 3 #include <stack>
 4 #include <cstdio>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <bitset>
 9 #include <algorithm>
10 #include <cmath>
11 #include <cstring>
12 #include <cstdlib>
13 #include <string>
14 #include <sstream>
15 #include <time.h>
16 #define x first
17 #define y second
18 #define pb push_back
19 #define mp make_pair
20 #define lson l,m,rt*2
21 #define rson m+1,r,rt*2+1
22 #define mt(A,B) memset(A,B,sizeof(A))
23 #define lowbit(x) (x&(-x))
24 using namespace std;
25 typedef long long LL;
26 typedef unsigned long long ull;
27 const double PI = acos(-1);
28 const int N=1e6+10;
29 //const int M=1e6+10;
30 const LL mod=1e9;
31 const int inf = 0x3f3f3f3f;
32 const LL INF=0x3f3f3f3f3f3f3f3fLL;
33 const double esp=1e-10;
34 int a[N],vis[N],lpos[N],Ma[N<<2];
35 LL sum[N];
36 void pushUp(int rt)
37 {
38     Ma[rt]=max(Ma[rt*2],Ma[rt*2+1]);
39 }
40 void update(int pos,int val,int l,int r,int rt)
41 {
42     if(l==r)
43     {
44         Ma[rt]=val;return;
45     }
46     int m=(l+r)/2;
47     if(pos<=m)update(pos,val,lson);
48     else update(pos,val,rson);
49     pushUp(rt);
50 }
51 int query(int L,int R,int l,int r,int rt)
52 {
53     int ans=-inf;
54     if(L<=l&&r<=R)return Ma[rt];
55     int m=l+(r-l)/2;
56     if(L<=m)ans=max(ans,query(L,R,lson));
57     if(R>m)ans=max(ans,query(L,R,rson));
58     return ans;
59 }
60 int main()
61 {
62 #ifdef Local
63     freopen("data.h","r",stdin);
64 #endif
65     //ios::sync_with_stdio(false);
66     //cin.tie(0);
67     
68 #ifdef Local
69     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
70 #endif
71 }
View Code

 

 

代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<math.h>
 6 #include<vector>
 7 #include<queue>
 8 #include<stack>
 9 #include<map>
10 using namespace std;
11 typedef long long ll;
12 const int maxn=1e6+10;
13 const int INF=0x3f3f3f3f;
14 const double eps=1e-10;
15 #define mt(A,B) memset(A,B,sizeof(A))
16 #define lson l,m,rt*2
17 #define rson m+1,r,rt*2+1
18 ll v[maxn],vis[maxn],lpos[maxn],tree[maxn<<2],sum[maxn];
19 void pushup(ll rt)
20 {
21     tree[rt]=max(tree[rt<<1],tree[rt<<1+1]);
22 }
23 void update(ll pos,ll val,ll l,ll r,ll rt)
24 {
25     if(l==r)
26     {
27         tree[rt]=val;
28         return ;
29     }
30     ll m=(l+r)>>1;
31     if(pos<=m) update(pos,val,lson);
32     else update(pos,val,rson);
33     pushup(rt);
34 }
35 ll query(ll L,ll R,ll l,ll r,ll rt)
36 {
37     ll ans=0;
38     if(L<=l && R>=r)
39         return tree[rt];
40     ll m=(l+r)>>1;
41     if(L<=m) ans=max(ans,query(L,R,lson));
42     if(R>m) ans=max(ans,query(L,R,rson));
43     return ans;
44 }
45 int main()
46 {
47     ll n,m;
48     while(~scanf("%lld%lld",&n,&m))
49     {
50         mt(vis,0);
51         for(ll i=1; i<=n; i++)
52             scanf("%lld",&v[i]);
53         sum[0]=0;
54         for(ll i=1; i<=n; i++)
55         {
56             if(!vis[v[i]])
57             {
58                 vis[v[i]]=i;
59                 lpos[i]=0;
60             }
61             else
62             {
63                 lpos[i]=vis[v[i]];
64                 vis[v[i]]=i;
65             }
66             sum[i]=sum[i-1]+v[i]*1LL;
67         }
68         for(ll i=1; i<=n; i++)update(i,lpos[i],1,n,1);
69         for(ll i=0; i<m; i++)
70         {
71             ll l,r;
72             scanf("%lld%lld",&l,&r);
73             if(sum[r]-sum[l-1]==1LL*(r-l+2)*(r-l+1)/2)
74             {
75                 if(query(l,r,1,n,1)<l)printf("YES\n");
76                 else printf("NO\n");
77             }
78             else printf("NO\n");
79         }
80     }
81     return 0;
82 }
View Code

 

posted @ 2020-04-23 13:18  kongbursi  阅读(280)  评论(0编辑  收藏  举报