#RMQ,动态开点线段树#CF803G Periodic RMQ Problem
题目
给定\(n\)个数,将这个数列复制\(k\)次得到数列\(a\),
对\(a\)满足区间赋值操作和区间最小值询问
\(n\leq 10^5,q\leq 10^5,k\leq 10^4即|a|\leq 10^9\)
分析
先考虑线段树的区间赋值和区间最小值询问,如果没有复制那就是基本操作,
考虑一个很大的变化就是不可能将整棵线段树完全建好,
考虑动态开点线段树,每当新开一个点时,就先赋值为最小值,
这样线段树的大小为\(O(q\log|a|)\),区间赋值和区间最小值照常完成,
所以问题就转换成快速求未改动时区间最小值,这个用RMQ做就可以了,
如果该区间长度不短于\(n\)就直接是原来\(n\)个数的最小值,
否则如果这一段跨越了复制点,就维护前缀最小值和后缀最小值拼凑,
如果区间在一段内直接用RMQ
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=100011;
int f[N][17],two[17],lg[N],pre[N],suf[N],w[N<<6],lazy[N<<6],root,ls[N<<6],rs[N<<6],cnt,n,m;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed RMQ(int l,int r){
rr int z=lg[r-l+1];
return min(f[l][z],f[r-two[z]+1][z]);
}
inline signed answ(int l,int r){
if (r-l+1>=n) return pre[n];
rr int posl=(l-1)/n+1,posr=(r-1)/n+1;
l-=(posl-1)*n,r-=(posr-1)*n;
return (posl==posr)?RMQ(l,r):min(suf[l],pre[r]);
}
inline void update(int &k,int l,int r,int x,int y,int z){
if (!k) w[k=++cnt]=answ(l,r);
if (l==x&&r==y) {w[k]=lazy[k]=z; return;}
rr int mid=(l+r)>>1;
if (lazy[k]){
if (!ls[k]) ls[k]=++cnt;
if (!rs[k]) rs[k]=++cnt;
w[ls[k]]=lazy[ls[k]]=lazy[k],
w[rs[k]]=lazy[rs[k]]=lazy[k],
lazy[k]=0;
}
if (y<=mid){
if (!rs[k]) w[rs[k]=++cnt]=answ(mid+1,r);
update(ls[k],l,mid,x,y,z);
}
else if (x>mid){
if (!ls[k]) w[ls[k]=++cnt]=answ(l,mid);
update(rs[k],mid+1,r,x,y,z);
}
else update(ls[k],l,mid,x,mid,z),update(rs[k],mid+1,r,mid+1,y,z);
w[k]=min(w[ls[k]],w[rs[k]]);
}
inline signed query(int &k,int l,int r,int x,int y){
if (!k) w[k=++cnt]=answ(l,r);
if (l==x&&r==y) return w[k];
rr int mid=(l+r)>>1;
if (lazy[k]){
if (!ls[k]) ls[k]=++cnt;
if (!rs[k]) rs[k]=++cnt;
w[ls[k]]=lazy[ls[k]]=lazy[k],
w[rs[k]]=lazy[rs[k]]=lazy[k],
lazy[k]=0;
}
if (y<=mid) return query(ls[k],l,mid,x,y);
else if (x>mid) return query(rs[k],mid+1,r,x,y);
else return min(query(ls[k],l,mid,x,mid),query(rs[k],mid+1,r,mid+1,y));
}
signed main(){
n=iut(),m=iut(),lg[0]=-1,two[0]=1,pre[0]=suf[n+1]=1e9+7;
for (rr int i=1;i<17;++i) two[i]=two[i-1]<<1;
for (rr int i=1;i<=n;++i) f[i][0]=iut(),lg[i]=lg[i>>1]+1;
for (rr int i=1;i<=n;++i) pre[i]=min(pre[i-1],f[i][0]);
for (rr int i=n;i>=1;--i) suf[i]=min(suf[i+1],f[i][0]);
for (rr int j=1;j<=lg[n];++j)
for (rr int i=1;i+two[j]-1<=n;++i)
f[i][j]=min(f[i][j-1],f[i+two[j-1]][j-1]);
for (rr int T=iut();T;--T){
rr int opt=iut(),l=iut(),r=iut();
if (opt==1) update(root,1,n*m,l,r,iut());
else print(query(root,1,n*m,l,r)),putchar(10);
}
return 0;
}
#RMQ,动态开点线段树#CF803G Periodic RMQ Problem的更多相关文章
- Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树
思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用 lazy=0 没被覆盖过 els ...
- [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)
题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
4636: 蒟蒻的数列 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 247 Solved: 113[Submit][Status][Discuss ...
- codeforces 893F - Physical Education Lessons 动态开点线段树合并
https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...
- codeforces 915E - Physical Education Lessons 动态开点线段树
题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...
- CF915E Physical Education Lessons 动态开点线段树
题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- NOIP2017 列队——动态开点线段树
Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为 ...
- 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)
题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...
随机推荐
- 国内无法下载k8s镜像的解决办法
关于通过各种方法下载k8s相关镜像的方法总结如下: 1.使用Azure中国镜像站,目前限制只能"Azure China IP"可用,不再对外提供服务,此路不通. 2.直接使用mir ...
- 【ACM专项练习#02】输入整行字符串、输入值到vector、取输入整数的每一位
输入整行字符串 平均绩点 题目描述 每门课的成绩分为A.B.C.D.F五个等级,为了计算平均绩点,规定A.B.C.D.F分别代表4分.3分.2分.1分.0分. 输入 有多组测试样例.每组输入数据占一行 ...
- 为产品的一堆Visual Studio解决方案引入Directory.Build.props
为什么需要Directory.Build.props? 一个产品有了多个甚至几十个解决方案之后,每个解决方案里面的项目可能会引用一个dll包的不同版本,因此需要集中管理dll包的版本号. .NET的D ...
- 【Azure Developer】Azure REST API: 如何通过 API查看 Recovery Services Vaults(恢复保管库)的备份策略信息? 如备份中是否含有虚拟机的Disk
问题描述 如何通过 API查看 Recovery Services Vaults(恢复保管库)的备份策略信息? 如备份中是否含有虚拟机的Disk.在Azure门户中可以通过查看Backup Item查 ...
- 【Azure 应用服务】App Service For Linux 怎么安装Composer,怎么安装PHP扩展,怎么来修改站点根路径启动程序?
问题一:App Service 的默认启动路径为wwwroot,如何修改到到PHP代码运行目录呢? 如Laravel的启动目录为public/?那如何修改呢? App Service 的默认 PHP ...
- 【对比】Gemini:听说GPT-4你小子挺厉害
前言 缘由 谷歌连放大招:Gemini Pro支持中文,Bard学会画画 事情起因: 一心只读圣贤书的狗哥,不经意间被新闻吸引.[谷歌最新人工智能模型Gemini Pro已在欧洲上市 将与ChatGP ...
- C++ //常用拷贝和替换算法 //copy //replace 将指定区间范围内的旧元素修改为新元素 //replace_if(满足条件的元素,替换指定的元素) //swap 互换两个容器的元素
//常用拷贝和替换算法 //copy //replace 将指定区间范围内的旧元素修改为新元素 //replace_if(满足条件的元素,替换指定的元素) //swap 互换两个容器的元素 #incl ...
- 【MongoDB详细步骤】(内附源码)
第01章-MongoDB 1.安装和启动(docker方式) 1.1.拉取镜像 docker pull mongo:4.4.8 1.2.创建和启动容器 docker run -d --restart= ...
- Nginx安装nginx-rtmp-module模块
简介 nginx中的模块虽然就是类似插件的概念,但是它无法像VsCode那样轻松的安装扩展. nginx要安装其它模块必须同时拿到nginx源代码和模块源代码,然后手动编译,将模块打到nginx中,最 ...
- 四种方式实现点击chrome链接在ie中显示页面
1.c++ socket通过浏览器在ie中打开指定url github源码:https://github.com/iamzken/cpp-open-ie 2.vb生成exe,url访问exe启动ie并 ...