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. Kendo ui 入门知识点

    1. Kendo的继承 varPerson= kendo.Class.extend({...}); var person = new person(); var Parent = kendo.Clas ...

  2. 基于centos7下appium环境搭建

    事件背景: 前几日在群里看到关总说他的server端是搭建在linux环境下,包括对客户端与服务端的交互处理,感觉整体思路清晰可鉴,于是就想尝试,动手实践,接着从环境搭建开始搞起,于是就有了这篇文章, ...

  3. [转]ASCII码表及扩展ASCII码表,方便查阅

    ASCII码表可以看成由三部分组成: 第一部分:由00H到1FH共32个,一般用来通讯或作为控制之用.有些可以显示在屏幕上,有些则不能显示,但能看到其效果(如换行.退格).如下表: 第二部分:是由20 ...

  4. HTML阻止冒泡事件的发生

    阻止事件冒泡函数(低级标签的点击事件触发后,上级标签的点击事件再触发,此函数就是防止冒泡事件发生) function stopEventBubble(event){ var e=event || wi ...

  5. 使用Eclipse进行Makefile项目

    最近在MCU on Eclipse网站上看到Erich Styger所写的一篇有关在Eclipse中使用Makefile创建项目的文章,文章讲解清晰明了非常不错,所以呢没人将其翻译过来供各位同仁参考. ...

  6. Confluence 6 使用电子邮件可见

    Confluence 提供了 3 个电子邮件策略,这些策略 Confluence 管理员可以通过管理员控制台(Administration Console)进行配置: 公开(Public):电子邮件地 ...

  7. 用flask的扩展实现的简单的页面登录

    from flask import Flask,render_template,request,redirect,session app = Flask(__name__,template_folde ...

  8. tp3.2 事务

    public function exchangeTransfer($user_id, $type, $money, $config, $other_id = 0) { $r['code'] = ERR ...

  9. 解决beego中同时开启http和https时,https端口占用问题

    在beego的app.go文件中, 找到 // run normal mode if BConfig.Listen.EnableHTTPS { go func() { time.Sleep( * ti ...

  10. python DLL接口测试

    #coding=utf-8 import clr import sys import threading from itertools import permutations sys.path.app ...