【模拟8.05】优美序列(线段树 分块 ST算法)
如此显然的线段树,我又瞎了眼了
事实上跟以前的奇袭很像.......
只要满足公式maxn-minn(权值)==r-l即可
所以可以考虑建两颗树,一棵节点维护位置,一棵权值,
每次从一棵树树上查询信息,如果满足公式就停止,不然两颗树不断扩展区间
当然也可以用ST啦(查询O(1)优于线段树)
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<string>
6 #include<set>
7 #include<map>
8 #include<vector>
9 #include<cmath>
10 #define int long long
11 #define MAXN 100101
12 using namespace std;
13 char buffer[1<<20|1],*S,*T;
14 #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,1<<20|1,stdin),S==T))?EOF:*S++)
15 int read()
16 {
17 int x=0;char c=getchar();
18 while(c<'0'||c>'9')c=getchar();
19 while(c>='0'&&c<='9')
20 {
21 x=(x<<1)+(x<<3)+(c^48);
22 c=getchar();
23 }
24 return x;
25 }
26 int a[MAXN];
27 int maxn,minn;
28 int n,m;int binn[MAXN];
29 int f[21][MAXN];int f_min[21][MAXN];//区间极值的最小位置,最大位置
30 int wei[21][MAXN];int wei_min[21][MAXN];
31 void work()
32 {
33 int t=log(n)/log(2);
34 for(int j=1;j<=t;++j)
35 {
36 for(int i=1;i<=(n+1-binn[j]);++i)
37 {
38 f[j][i]=max(f[j-1][i],f[j-1][i+binn[j-1]]);
39 f_min[j][i]=min(f_min[j-1][i],f_min[j-1][i+binn[j-1]]);
40 wei[j][i]=max(wei[j-1][i],wei[j-1][i+binn[j-1]]);
41 wei_min[j][i]=min(wei_min[j-1][i],wei_min[j-1][i+binn[j-1]]);
42 }
43 }
44 }
45 int maxn_wei,minn_wei;
46 void RMB(int l,int r)
47 {
48 int t=log(r-l+1)/log(2);
49 maxn_wei=max(f[t][l],f[t][r+1-binn[t]]);
50 minn_wei=min(f_min[t][l],f_min[t][r+1-binn[t]]);
51 return ;
52 }
53
54 void RMB_wei(int l,int r)
55 {
56 int t=log(r-l+1)/log(2);
57 maxn=max(wei[t][l],wei[t][r+1-binn[t]]);
58 minn=min(wei_min[t][l],wei_min[t][r+1-binn[t]]);
59 return ;
60 }
61 signed main()
62 {
63 n=read();
64 for(int i=1;i<=n;++i)
65 {
66 a[i]=read();
67 f[0][a[i]]=i;f_min[0][a[i]]=i;
68 wei[0][i]=a[i];wei_min[0][i]=a[i];
69 }
70 binn[0]=1;
71 for(int i=1;i<=20;++i)binn[i]=(binn[i-1]<<1);
72 work();
73 m=read();
74 for(int i=1;i<=m;++i)
75 {
76 int l,r;
77 l=read();r=read();
78 maxn=0;minn=0x7ffffffff;maxn_wei=r;minn_wei=l;
79 while(maxn-minn!=maxn_wei-minn_wei)
80 {
81 RMB_wei(minn_wei,maxn_wei);
82 RMB(minn,maxn);
83 }
84 printf("%lld %lld\n",minn_wei,maxn_wei);
85 }
86 }
80 超时
100分:
%%%%%skyh 分块思想碾爆tarjan正解
因为每次区间不断扩展可能会扩展好多边,
那么我们把区间分块,这样预处理出块与块的答案
在实际查询中如果发现当前查询区间大于块的区间,那就可以判断是否用块跳跃
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<string>
6 #include<set>
7 #include<map>
8 #include<vector>
9 #include<cmath>
10 #define int long long
11 #define MAXN 100101
12 using namespace std;
13 int kuan[MAXN];int belong[MAXN];
14 char buffer[1<<20|1],*S,*T;
15 #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,1<<20|1,stdin),S==T))?EOF:*S++)
16 inline void read(int &x){x=0;
17 register char c=getchar();
18 while(c<'0'||c>'9')c=getchar();
19 while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=getchar();
20 }
21 int a[MAXN];
22 int maxn,minn;int maxn_wei,minn_wei;
23 int n,m;int binn[MAXN];
24 int f[21][MAXN];int f_min[21][MAXN];//区间极值的最小位置,最大位置
25 int wei[21][MAXN];int wei_min[21][MAXN];
26 int ans_l[1000][1000];
27 int ans_r[1000][1000];
28 int tt,base;int Log[MAXN];
29 void RMB(int l,int r)//通过权值查位置
30 {
31 int t=Log[r-l+1];
32 maxn_wei=max(f[t][l],f[t][r+1-binn[t]]);
33 minn_wei=min(f_min[t][l],f_min[t][r+1-binn[t]]);
34 return ;
35 }
36 void RMB_wei(int l,int r)//通过位置察权值
37 {
38 int t=Log[r-l+1];
39 maxn=max(wei[t][l],wei[t][r+1-binn[t]]);
40 minn=min(wei_min[t][l],wei_min[t][r+1-binn[t]]);
41 return ;
42 }
43 void work()
44 {
45 int t=Log[n];
46 for(int j=1;j<=t;++j)
47 {
48 for(int i=1;i<=(n+1-binn[j]);++i)
49 {
50 f[j][i]=max(f[j-1][i],f[j-1][i+binn[j-1]]);
51 f_min[j][i]=min(f_min[j-1][i],f_min[j-1][i+binn[j-1]]);
52 wei[j][i]=max(wei[j-1][i],wei[j-1][i+binn[j-1]]);
53 wei_min[j][i]=min(wei_min[j-1][i],wei_min[j-1][i+binn[j-1]]);
54 }
55 }
56 for(int i=1;i<base;++i)
57 {
58 for(int j=i+1;j<=base;++j)
59 {
60 int l=kuan[i],r=kuan[j];//位置查权值
61 maxn=0;minn=0x7ffffffff;maxn_wei=r;minn_wei=l;
62 while(maxn-minn!=maxn_wei-minn_wei)
63 {
64 RMB_wei(minn_wei,maxn_wei);
65 RMB(minn,maxn);
66 }
67 ans_l[i][j]=minn_wei;ans_r[i][j]=maxn_wei;
68 // printf("ansl[%lld][%lld] i=%lld j=%lld\n",minn_wei,maxn_wei,i,j);
69 }
70 }
71 }
72
73 signed main()
74 {
75 read(n);
76 tt=pow(n,0.66666);
77 Log[0]=-1;for(register int i=1;i<=n;++i) Log[i]=Log[i>>1]+1;
78 for(int i=1;i;++i)
79 {
80 if(i*tt>=n)
81 {
82 kuan[i]=n;
83 base=i;
84 break;
85 }
86 else
87 kuan[i]=i*tt;
88 }
89 for(int i=1;i<=n;++i)
90 {
91 read(a[i]);
92 f[0][a[i]]=i;f_min[0][a[i]]=i;
93 wei[0][i]=a[i];wei_min[0][i]=a[i];
94 belong[i]=((i-1)/tt)+1;
95 }
96 binn[0]=1;
97 for(int i=1;i<=20;++i)binn[i]=(binn[i-1]<<1);
98 work();
99 read(m);
100 for(int i=1;i<=m;++i)
101 {
102 int l,r;
103 read(l);read(r);
104 maxn=0;minn=0x7ffffffff;
105 maxn_wei=r;minn_wei=l;
106 RMB_wei(minn_wei,maxn_wei);
107 while(maxn-minn!=maxn_wei-minn_wei)
108 {
109 //printf("maxn=%lld minn=%lld maxn_wei=%lld minwei=%lld\n",maxn,minn,maxn_wei,minn_wei);
110 RMB(minn,maxn);
111 int one=belong[minn_wei],two=belong[maxn_wei];
112 //printf("one=%lld two=%lld\n",one,two);
113 if(two>one+1&&one-1!=0)
114 {
115 if(ans_l[one][two-1]<=minn_wei&&ans_r[one][two-1]>=maxn_wei)
116 {
117 minn_wei=ans_l[one][two-1];
118 maxn_wei=ans_r[one][two-1];
119 //printf("min_wei=%lld ma_wei=%lld\n",minn_wei,maxn_wei);
120 }
121 }
122 //printf("maxn=%lld minn=%lld maxn_wei=%lld minwei=%lld\n",maxn,minn,maxn_wei,minn_wei);
123 RMB_wei(minn_wei,maxn_wei);
124 if(maxn-minn==maxn_wei-minn_wei)break;
125 }
126 printf("%lld %lld\n",minn_wei,maxn_wei);
127 }
128 }
%%%天皇
【模拟8.05】优美序列(线段树 分块 ST算法)的更多相关文章
- bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...
- 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树
[题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- 洛谷 P5897 - [IOI2013]wombats(决策单调性优化 dp+线段树分块)
题面传送门 首先注意到这次行数与列数不同阶,列数只有 \(200\),而行数高达 \(5000\),因此可以考虑以行为下标建线段树,线段树上每个区间 \([l,r]\) 开一个 \(200\times ...
- IOI 2013 袋熊(线段树+分块+决策单调性)
题意 http://www.ioi2013.org/wp-content/uploads/tasks/day1/wombats/Wombats%20zh%20(CHN).pdf 思路 我们设矩形的 ...
- BZOJ 1798 (线段树||分块)的标记合并
我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...
- BZOJ1095 [ZJOI2007] Hide 捉迷藏 (括号序列 + 线段树)
题意 给你一颗有 \(n\) 个点的树 , 共有 \(m\) 次操作 有两种类别qwq 将树上一个点染黑/白; 询问树上最远的两个黑点的距离. \((n \le 200000, m ≤500000)\ ...
- [luogu1198][bzoj1012][JSOI2008]最大数【线段树+分块】
题目描述 区间查询最大值,结尾插入,强制在线. 分析 线段树可以做,但是练了一下分块,发现自己打错了两个地方,一个是分块的地方把/打成了%,还有是分块的时候标号要-1. 其他也没什么要多讲的. 代码 ...
- L3-2 森森快递 (30 分)(贪心+线段树/分块)
题目链接:https://pintia.cn/problem-sets/1108203702759940096/problems/1108204121661857798 题目大意: 森森开了一家快递公 ...
随机推荐
- Hbase问题小结(一)
1. Hbase读写优化 写: 批量写.异步批量提交.多线程并发写.使用BulkLoad写入.表优化(压缩算法.预分区.合理的rowkey设计.合理关闭WAL或异步WAL) SKIP_WAL:只写缓存 ...
- 集成Spring Data JPA
1.Spring Data JPA简介 Spring Data是一个用于简化数据访问,并支持云服务的开源框 使用完成Spring Data JPA对user表的CRUD操作. 2.步骤 1.创建工程勾 ...
- Java GUI学习,贪吃蛇小游戏
JAVA GUI练习 贪吃蛇小游戏 前几天虽然生病了,但还是跟着狂神学习了GUI的方面,跟着练习了贪吃蛇的小项目,这里有狂神写的源码点我下载,还有我跟着敲的点我下载,嘿嘿,也就注释了下重要的地方,这方 ...
- Windows系统下consul的安装、启动、配置
阅读时长:3分钟 操作系统:Windows10 一.consul的安装 首先在consul.exe文件目录下的地址栏中输入cmd. 接着输入consul指令,敲击回车安装consul. 安装成功后会有 ...
- 【转载】一次「Too many open files」故障
一次「Too many open files」故障 发表于2015-08-02 昨天,项目的 ElasticSearch 服务挂了,我说的挂可不是进程没了,因为有 Supervisor 保护,而是服务 ...
- 攻防世界(六)supersqli
攻防世界系列:supersqli 方法一: 用逗号包裹回显正常,说明存在注入 1';--+(注释符也可用 -- 或 # 发现均未被过滤!) 有order by 语句可知表由2个字段,使用联合查询 (想 ...
- 012.Python的字典和集合的相关函数
一 字典的相关函数 1.1 增函数 dictvar = {"a":1,"b":2} dictvar["c"] = 3 print(dictv ...
- 1、大数据 Hadoop配置和单机Hadoop系统配置
#查看服务器ip ip add #设置主机名称 hostnamectl set-hostname master bash #查看 hostname #绑定ip vi /etc/hosts 添加 服务器 ...
- https 真的安全吗,可以抓包吗,如何防止抓包吗
Android_interview github 地址 大家好,我是程序员徐公,加上实习,有五年中大厂经验.自荐一下,可以关注我的微信公众号程序员徐公 公众号程序员徐公回复黑马,获取 Android ...
- 有关Git基础操作的学习
Git简介 Git是一个免费的开源 分布式版本控制系统,旨在快速高效地处理从小型到大型项目的所有内容. Git 易于学习, 占地面积小,具有闪电般的快速性能.它具有诸如Subversion,CVS,P ...