【模拟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 题目大意: 森森开了一家快递公 ...
随机推荐
- Java安全之FastJson JdbcRowSetImpl 链分析
Java安全之FastJson JdbcRowSetImpl 链分析 0x00 前言 续上文的Fastjson TemplatesImpl链分析,接着来学习JdbcRowSetImpl 利用链,Jdb ...
- Spring Cloud 升级之路 - 2020.0.x - 5. 理解 NamedContextFactory
spring-cloud-commons 中参考了 spring-cloud-netflix 的设计,引入了 NamedContextFactory 机制,一般用于对于不同微服务的客户端模块使用不同的 ...
- 基于混合云模式的calico部署
开始前准备 确定calico数据存储 Calico同时支持kubernetes api和etcd数据存储.官方给出的建议是在本地部署中使用K8S API,仅支持Kubernetes模式.而官方给出的e ...
- [bug] CDH 安装 Error : No matching Packages to list
信息 分析 我的系统是CentOS 7,而 cm 安装包是配合 redhat 6 的,应该选择 redhat 7 目录下的包 参考 https://community.cloudera.com/t5/ ...
- Centos7如何安装开源办公软件Libreoffice
在Centos7安装了WPS,但是用了没两月就出问题,无法正常使用.(准确来说,安装的WPS一直都有各种问题存在,但是没有影响到主要功能也就将就着用,后来是直接输入不了文字) 既然是开源系统,自然而然 ...
- SSH 远程控制
本文以 Ubuntu 20.04(客户端) 控制 Kali Linux 2020.2(服务端)为例 1.安装SSH(secure Shell) SSH分为客户端oppenssh-client和服务端o ...
- python基础之流程控制(if判断和while、for循环)
程序执行有三种方式:顺序执行.选择执行.循环执行 一.if条件判断 1.语句 (1)简单的 if 语句 (2)if-else 语句 (3)if-elif-else 结构 (4)使用多个 elif 代码 ...
- shell基础之综合练习
0.脚本一键完成下面所有操作1.准备2台centos7系统的服务器,远程互相免密登录,以下所有题目过程中开启防火墙2.给1号机和2号机使用光盘搭建本地yum源(永久生效)3.给服务器1添加2块硬盘,1 ...
- STM32 中的HARDFAULT 的查找方法
http://blog.csdn.net/zyboy2000/article/details/7668331
- 【Microstation】三维建模基础及软件入门到精通实验教程目录
@ 目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 MicroStation是一款非常不错的二维和三维设计软件,由奔特力(Bentley)工程软件系统有限公司开发的一款软件.在C ...