Periodic RMQ Problem

动态开点线段树直接搞, 我把它分成两部分, 一部分是原来树上的, 一部分是后来染上去的,两个部分取最小值。

感觉有点难写。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 2e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); int Log[N];
int MIN = inf;
struct ST {
int dp[N][], ty;
void build(int n, int b[], int _ty) {
ty = _ty;
for(int i = -(Log[]=-); i < N; i++)
Log[i] = Log[i - ] + ((i & (i - )) == );
for(int i = ; i <= n; i++) dp[i][] = ty * b[i];
for(int j = ; j <= Log[n]; j++)
for(int i = ; i + ( << j) - <= n; i++)
dp[i][j] = max(dp[i][j - ], dp[i + ( << (j - ))][j - ]);
}
int query(int x, int y) {
int k = Log[y - x + ];
return ty * max(dp[x][k], dp[y - ( << k) + ][k]);
}
} rmq; int n, k, q, a[N]; #define lson l, mid, a[x].ls
#define rson mid + 1, r, a[x].rs
namespace SGT1 {
int tot, Rt;
struct Node {
Node() {
mn = inf;
ls = rs = ;
lazy = inf;
}
int mn, ls, rs, lazy;
} a[N * ];
inline void pull(int x) {
a[x].mn = min(a[a[x].ls].mn, a[a[x].rs].mn);
}
inline void push(int x) {
if(a[x].lazy < inf) {
if(!a[x].ls) a[x].ls = ++tot;
if(!a[x].rs) a[x].rs = ++tot;
int lazy = a[x].lazy, l = a[x].ls, r = a[x].rs;
a[l].mn = lazy;
a[r].mn = lazy;
a[l].lazy = lazy;
a[r].lazy = lazy;
a[x].lazy = inf;
}
}
void update(int L, int R, int val, int l, int r, int& x) {
if(!x) x = ++tot;
if(l >= L && r <= R) {
a[x].mn = val;
a[x].lazy = val;
return;
}
push(x);
int mid = l + r >> ;
if(L <= mid) update(L, R, val, lson);
if(R > mid) update(L, R, val, rson);
pull(x);
}
int query(int L, int R, int l, int r, int x) {
if(l >= L && r <= R) return a[x].mn;
push(x);
int mid = l + r >> ;
if(R <= mid) return query(L, R, lson);
else if(L > mid) return query(L, R, rson);
else return min(query(L, R, lson), query(L, R, rson));
}
} namespace SGT2 {
int tot, Rt;
struct Node {
Node() {
ls = rs = ;
mn = inf;
vis = false;
}
int mn, ls, rs;
bool vis;
} a[N * ];
void update(int L, int R, int l, int r, int& x) {
if(!x) {
x = ++tot;
if(r - l + >= n) a[x].mn = MIN;
else {
int be = (l - ) % n + ;
int ed = be + (r - l);
a[x].mn = rmq.query(be, ed);
}
}
if(a[x].vis) return;
if(l >= L && r <= R) {
a[x].mn = inf;
a[x].vis = true;
return;
}
int mid = l + r >> ;
if(R <= mid) {
update(L, R, lson);
if(!a[x].rs) {
a[x].rs = ++tot;
if(r - mid >= n) {
a[a[x].rs].mn = MIN;
} else {
int be = (mid) % n + ;
int ed = be + (r - mid) - ;
a[a[x].rs].mn = rmq.query(be, ed);
}
}
} else if(L > mid) {
update(L, R, rson);
if(!a[x].ls) {
a[x].ls = ++tot;
if(mid - l + >= n) {
a[a[x].ls].mn = MIN;
} else {
int be = (l - ) % n + ;
int ed = be + (mid - l);
a[a[x].ls].mn = rmq.query(be, ed);
}
}
} else {
update(L, R, lson);
update(L, R, rson);
}
a[x].mn = min(a[a[x].ls].mn, a[a[x].rs].mn);
}
int query(int L, int R, int l, int r, int& x) {
if(!x) {
x = ++tot;
if(r - l + >= n) a[x].mn = MIN;
else {
int be = (l - ) % n + ;
int ed = be + (r - l);
a[x].mn = rmq.query(be, ed);
}
}
if(a[x].vis) return inf;
if(l >= L && r <= R) return a[x].mn;
int mid = l + r >> ;
if(R <= mid) return query(L, R, lson);
else if(L > mid) return query(L, R, rson);
else return min(query(L, R, lson), query(L, R, rson));
}
} int main() {
scanf("%d%d", &n, &k);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
a[i + n] = a[i];
MIN = min(MIN, a[i]);
}
rmq.build( * n, a, -);
scanf("%d", &q);
while(q--) {
int op; scanf("%d", &op);
if(op == ) {
int L, R, x;
scanf("%d%d%d", &L, &R, &x);
SGT1::update(L, R, x, , n * k, SGT1::Rt);
SGT2::update(L, R, , n * k, SGT2::Rt);
} else {
int L, R;
scanf("%d%d", &L, &R);
printf("%d\n", min(SGT1::query(L, R, , n * k, SGT1::Rt), SGT2::query(L, R, , n * k, SGT2::Rt)));
}
}
return ;
} /*
*/

简化

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 2e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); int Log[N];
int MIN = inf;
struct ST {
int dp[N][], ty;
void build(int n, int b[], int _ty) {
ty = _ty;
for(int i = -(Log[]=-); i < N; i++)
Log[i] = Log[i - ] + ((i & (i - )) == );
for(int i = ; i <= n; i++) dp[i][] = ty * b[i];
for(int j = ; j <= Log[n]; j++)
for(int i = ; i + ( << j) - <= n; i++)
dp[i][j] = max(dp[i][j - ], dp[i + ( << (j - ))][j - ]);
}
int query(int x, int y) {
int k = Log[y - x + ];
return ty * max(dp[x][k], dp[y - ( << k) + ][k]);
}
} rmq; int n, k, q, a[N]; inline int getVal(int l, int r) {
if(r - l + >= n) return MIN;
int be = (l - ) % n + ;
int ed = be + (r - l);
return rmq.query(be, ed);
} #define lson l, mid, a[x].ls
#define rson mid + 1, r, a[x].rs
namespace SGT {
int tot, Rt;
struct Node {
Node() {
mn = inf;
ls = rs = ;
lazy = inf;
}
int mn, ls, rs, lazy;
} a[N * ];
inline void pull(int x) {
a[x].mn = min(a[a[x].ls].mn, a[a[x].rs].mn);
}
inline void push(int x, int l, int r) {
int mid = l + r >> ;
if(!a[x].ls) {
a[x].ls = ++tot;
a[a[x].ls].mn = getVal(l, mid);
}
if(!a[x].rs) {
a[x].rs = ++tot;
a[a[x].rs].mn = getVal(mid + , r);
}
if(a[x].lazy < inf) {
int lazy = a[x].lazy, l = a[x].ls, r = a[x].rs;
a[l].mn = lazy;
a[r].mn = lazy;
a[l].lazy = lazy;
a[r].lazy = lazy;
a[x].lazy = inf;
}
}
void update(int L, int R, int val, int l, int r, int& x) {
if(!x) x = ++tot;
if(l >= L && r <= R) {
a[x].mn = val;
a[x].lazy = val;
return;
}
push(x, l, r);
int mid = l + r >> ;
if(L <= mid) update(L, R, val, lson);
if(R > mid) update(L, R, val, rson);
pull(x);
}
int query(int L, int R, int l, int r, int x) {
if(l >= L && r <= R) {
if(!x) return getVal(l, r);
return a[x].mn;
}
push(x, l, r);
int mid = l + r >> ;
if(R <= mid) return query(L, R, lson);
else if(L > mid) return query(L, R, rson);
else return min(query(L, R, lson), query(L, R, rson));
}
} int main() {
scanf("%d%d", &n, &k);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
a[i + n] = a[i];
MIN = min(MIN, a[i]);
}
rmq.build( * n, a, -);
scanf("%d", &q);
while(q--) {
int op; scanf("%d", &op);
if(op == ) {
int L, R, x;
scanf("%d%d%d", &L, &R, &x);
SGT::update(L, R, x, , n * k, SGT::Rt);
} else {
int L, R;
scanf("%d%d", &L, &R);
printf("%d\n", SGT::query(L, R, , n * k, SGT::Rt));
}
}
return ;
} /*
*/

指针

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 2e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); int Log[N];
int MIN = inf;
struct ST {
int dp[N][], ty;
void build(int n, int b[], int _ty) {
ty = _ty;
for(int i = -(Log[]=-); i < N; i++)
Log[i] = Log[i - ] + ((i & (i - )) == );
for(int i = ; i <= n; i++) dp[i][] = ty * b[i];
for(int j = ; j <= Log[n]; j++)
for(int i = ; i + ( << j) - <= n; i++)
dp[i][j] = max(dp[i][j - ], dp[i + ( << (j - ))][j - ]);
}
int query(int x, int y) {
int k = Log[y - x + ];
return ty * max(dp[x][k], dp[y - ( << k) + ][k]);
}
} rmq; int n, k, q, a[N]; inline int getVal(int l, int r) {
if(r - l + >= n) return MIN;
int be = (l - ) % n + ;
int ed = be + (r - l);
return rmq.query(be, ed);
} struct Node {
Node* ls, *rs;
int mn, lazy;
Node(int l, int r) {
ls = rs = NULL;
mn = getVal(l, r);
lazy = -;
}
}; #define lson l, mid, rt->ls
#define rson mid + 1, r, rt->rs inline void pull(Node* rt) {
rt->mn = min(rt->ls->mn, rt->rs->mn);
}
inline void push(Node* rt, int l, int r) {
int mid = l + r >> ;
if(!rt->ls) rt->ls = new Node(l, mid);
if(!rt->rs) rt->rs = new Node(mid + , r);
if(rt->lazy != -) {
rt->ls->mn = rt->ls->lazy = rt->lazy;
rt->rs->mn = rt->rs->lazy = rt->lazy;
rt->lazy = -;
}
} void update(int L, int R, int val, int l, int r, Node* rt) {
if(R < l || L > r) return;
if(l >= L && r <= R) {
rt->mn = rt->lazy = val;
return;
}
push(rt, l, r);
int mid = l + r >> ;
update(L, R, val, lson);
update(L, R, val, rson);
pull(rt);
} int query(int L, int R, int l, int r, Node* rt) {
if(R < l || L > r) return inf;
if(l >= L && r <= R) {
if(rt) return rt->mn;
else return getVal(l, r);
}
push(rt, l, r);
int mid = l + r >> ;
return min(query(L, R, lson), query(L, R, rson));
} int main() {
scanf("%d%d", &n, &k);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
a[i + n] = a[i];
MIN = min(MIN, a[i]);
}
rmq.build( * n, a, -);
Node* Rt = new Node(, n * k);
scanf("%d", &q);
while(q--) {
int op; scanf("%d", &op);
if(op == ) {
int L, R, x;
scanf("%d%d%d", &L, &R, &x);
update(L, R, x, , n * k, Rt);
} else {
int L, R;
scanf("%d%d", &L, &R);
printf("%d\n", query(L, R, , n * k, Rt));
}
}
return ;
} /*
*/

Codeforces 803G Periodic RMQ Problem 线段树的更多相关文章

  1. codeforces 803G Periodic RMQ Problem

    codeforces 803G Periodic RMQ Problem 题意 长度为\(1e5\)的数组复制\(1e4\)次,对新的数组进行区间覆盖和区间最小值查询两种操作,操作次数\(1e5\). ...

  2. Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

    思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 els ...

  3. bzoj 3489 A simple rmq problem - 线段树

    Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...

  4. CodeForces 52C Circular RMQ (线段树)

    线段树区间更新维护最小值...记得下放标记... 如果线段树上的一个完整区间被修改,那么最小值和最大值增加相应的值后不变, 会改变是因为一部分改变而另外一部分没有改变所以维护一下就好. 询问的时候也要 ...

  5. (WAWAWAWAWAWAW) G. Periodic RMQ Problem

    没有联通门 : Codeforces G. Periodic RMQ Problem /* Codeforces G. Periodic RMQ Problem MMP 什么动态开点线段树啊 ... ...

  6. AC日记——Periodic RMQ Problem codeforces 803G

    G - Periodic RMQ Problem 思路: 题目给一段序列,然后序列复制很多次: 维护序列很多次后的性质: 线段树动态开点: 来,上代码: #include <cstdio> ...

  7. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  8. CF803G - Periodic RMQ Problem 动态开点线段树 或 离线

    CF 题意 有一个长度为n × k (<=1E9)的数组,有区间修改和区间查询最小值的操作. 思路 由于数组过大,直接做显然不行. 有两种做法,可以用动态开点版本的线段树,或者离线搞(还没搞)( ...

  9. Codeforces Round #271 (Div. 2) F. Ant colony (RMQ or 线段树)

    题目链接:http://codeforces.com/contest/474/problem/F 题意简而言之就是问你区间l到r之间有多少个数能整除区间内除了这个数的其他的数,然后区间长度减去数的个数 ...

随机推荐

  1. Python2018-列表的相关操作

    列表中存放的数据是可以进行修改的,比如"增"."删"."改" .“查” "增"-----append, extend, ...

  2. ASP.NET Core之NLog使用

    1.新建ASP.NET Core项目 1.1选择项目 1.2选择.Net版本 2. 添加NLog插件 2.1 通过Nuget安装 2.2下载相关的插件 3.修改NLog配置文件 3.1添加NLog配置 ...

  3. Linux 安装Python和Django

    1.下载python源码包 网址: https://www.python.org/ 在Downloads中打开Source code 由于 Django1.11.15不兼容3.7版本的python 所 ...

  4. Truffle框架环境搭建

    注意:本教程需要Truffle4.0或者是更高的版本 以太坊的智能合约只是代码,和我们的纸质代码不同,此合同需要非常精确的方式理解 如果合同编码不正确,我们的交易可能会失败,会导致gas的损失,更不用 ...

  5. 本地http://localhost打不开怎么办

    本地http://localhost打不开怎么办 出自:http://jingyan.baidu.com/article/c45ad29cebb95a051753e2b6.html 学过计算机的都知道 ...

  6. 处理:“ORA-00257: archiver error. Connect internal only, until freed”的错误问题

    注:本文参考了< ORA-00257: archiver error. Connect internal only, until freed 错误的处理方法  > 一:问题背景: 今天在 ...

  7. Confluence 6 Cron 表达式

    一个 cron 表达式是以 6-7 时间字段来定义一个计划任务是如何按照时间被执行的.每一个字段中的数据库而已为数字或者是一些特定的字符串来进行表达.每一个字段是使用空格或者 tab 进行分隔的. 下 ...

  8. 在 Confluence 6 中禁用 workbox 应用通知

    如果你选择 不提供应用通知(does not provide in-app notifications): Confluence workbox 图标将不会可见同时用户也不能在这个服务器上访问 wor ...

  9. Confluence 6 配置管理员联系页面

    管理员联系页面是一个格式化的页面,这个页面能够允许 Confluence 用户在 Confluence 中向管理员发送消息(在这部分的内容,管理员是默认管理员用户组的成员). 有关用户组的解释,请参考 ...

  10. Django 之缓存

    一.缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcac ...