[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 }
代码:
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 }
[HDU-5172] 单点查询线段树的更多相关文章
- hdu 2795 Billboard 【线段树】
给出一个高为h,宽为w的广告板,有n张广告需要贴,从第一行开始贴,尽量靠左,输出每个广告最后贴在哪一行的 先一直想不通这样建树是为什么 后来看到一篇题解里面的一句话“直到找到一个满足条件的叶子节点” ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
Tunnel Warfare Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) Total Sub ...
- HDU 5861 Road(线段树 区间修改 单点查询)
Road Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- HDU 2795 Billboard 【线段树维护区间最大值&&查询变形】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2795 Billboard Time Limit: 20000/8000 MS (Java/Others) ...
- hdu 1541 Stars(线段树单点更新,区间查询)
题意:求坐标0到x间的点的个数 思路:线段树,主要是转化,根据题意的输入顺序,保证了等级的升序,可以直接求出和即当前等级的点的个数,然后在把这个点加入即可. 注意:线段树下标从1开始,所以把所有的x加 ...
- HDU 1394 逆序数 线段树单点跟新 | 暴力
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
随机推荐
- centos 6.5 下安装RabbitMQ-3.7.28 二进制版本
centos 6.5 下安装RabbitMQ-3.7.28 二进制版本 安装依赖: yum install -y ncurses-devel socat logrotatewxWidgets-deve ...
- innodb是怎么刷新日志缓冲的
当innodb把日志缓冲刷新到磁盘日志文件的时候,先会用一个mutex锁住缓冲区,刷新到所需要的位置,然后移动剩下的条目到缓冲区的前面,当mutex释放时,可能有超过一个事务已经准备好刷新其日志记录, ...
- Github Python计算器开源项目 二次开发--增加函数图形
先上原项目链接:https://github.com/xhf79/Calculator_pyqt python+Qt 开发的计算器 原项目界面和功能如图所示: 科学计算的内容基本都有,但按照项目的提示 ...
- CTFHub - Web(三)
密码口令: 弱口令: 1.随意输入账号密码,抓包, 2.右击,"Send to Intruder",打开选项卡Intruder,点击position,椭圆框处软件已经自动为我们把要 ...
- 【葵花宝典】All-in-One模式安装KubeSphere
1.准备 Linux 机器 2.google api受限下载 KubeKey export KKZONE=cn curl -sfL https://get-kk.kubesphere.io | VER ...
- Sentry(v20.12.1) K8S 云原生架构探索,JavaScript 性能监控之管理 Transactions
系列 Sentry-Go SDK 中文实践指南 一起来刷 Sentry For Go 官方文档之 Enriching Events Snuba:Sentry 新的搜索基础设施(基于 ClickHous ...
- STM32驱动LCD原理
TFTLCD即薄膜晶体管液晶显示器.它与无源TN-LCD.STN-LCD的简单矩阵不同,它在液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性 ...
- uni-app 开发随笔(踩坑记录)
这里总结一些uni-app开发时我遇到的坑 uni-app获取元素高度及屏幕高度(uni-app不可使用document) uni.getSystemInfo({ success: function( ...
- STL_list容器
一.List简介 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每 ...
- 基于Vue的npm组件库
前言(*❦ω❦) 思维导图可能有点高糊,有点太大了,项目和导图文件放到github或giteee上,这个思维导图也是我文章的架构,思维导图是用FeHelper插件生成的,这个是一款开源chrome插件 ...