【模拟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 题目大意: 森森开了一家快递公 ...
随机推荐
- 三、postman持久化及批量运行
一.设置环境变量 环境变量的引用为{{变量名}},运行脚本之前切记要在右上角选择对应脚本设置的环境变量后点击保存 二.设置全局变量 三.脚本导入导出及分享 1.导入脚本 2.导出脚本 3.分享脚本 四 ...
- IT培训软件测试怎么样,问问“过来人”!
经常看到有人在网上发帖子问:"XX培训(IT培训机构)怎么样,学过的老哥可以出来讲讲真话吗?"问这种问题的同学,来,站起来!我不得不在这儿说你两句:你要想知道一家IT培训机构到底怎 ...
- 并发容器-CopyOnWriteSet
CopyOnWriteSet 该容器与CopyOnWriteArrayList相似,也是读取时不加锁,任意线程可以读.写入时加锁创建一个新的容器,然后写入新元素. 内部用CopyOnWriteArra ...
- 缓冲流以及JAVA路径相关问题
缓冲流 缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO 次数,从而提高读写的效率. 字节缓冲流 按字节处理 字符缓冲流 按字符处理 实例练习:文 ...
- 如何通过Zoho Books门户管理供应商
作为一个企业,不管规模大小,都有自己的供应商来为业务提供相关的服务和配件.随着采购的频率和供应商数量的增加,采购的管理和付款的跟踪难度就会增加,进而影响到企业和供应商之间的关系. 为了解决这个问题,Z ...
- [项目] 淘淘商城 Part.2
商品列表查询 Easyui 商品添加 商品类目选择 图片上传 富文本编辑器使用 添加的实现 展示首页 略 分页插件 在SqlMapConfig.xml,配置一个plugin 在sql语句执行之前,添加 ...
- LDAP协议入门
LDAP协议入门(轻型目录访问协议) LDAP简介 轻型目录访问协议,全称:Lightweight Directory Access Protocol,缩写:LDAP,它是基于X.500标准的,但是简 ...
- 解决SSH自动断线,无响应的问题。
解决SSH自动断线,无响应的问题. 3 Replies 在连接远程SSH服务的时候,经常会发生长时间后的断线,或者无响应(无法再键盘输入). 总体来说有两个方法: 1.依赖ssh客户端定时发送心跳. ...
- mysql如何设置一个字段,里面是自增的序号(1,2,3,..........)。
[遇到问题] [可忽略] 想把以前写的留言板搬到我的网站上去,所以要在Mysql上创建一个一mu一样的数据库,表单,字段..................... userid这个字段忘记了如何添加, ...
- LTP--linux稳定性测试 linux性能测试 ltp压力测试 内核更新 稳定性测试
LTP--linux稳定性测试 linux性能测试 ltp压力测试 zhangzj1030关注14人评论33721人阅读2011-12-09 12:07:45 说明:在写这篇文章之前,本人也不曾了 ...