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. jqueryui插件slider的简单使用

    <!DOCTYPE html> <html> <head> <title>slider</title> <meta charset=& ...

  2. PHP IDE选择标准

    2017年11月17日09:35:01 这里记录一下PHP IDE的选择标准 1.  是否有错误提示, 对于一些 `缺少分号`, `花括号不配对`, `变量未定义就使用`等待的提示是要有的 2. 代码 ...

  3. mysql5.7 pxc

    pxc优点总结:可以达到时时同步,无延迟现象发生完全兼容MySQL对于集群中新节点的加入,维护起来很简单数据的强一致性不足之处总结:只支持Innodb存储引擎存在多节点update更新问题,也就是写放 ...

  4. python序列(列表,元组,字典)的增删改查

    列表 操作 列表 方法 示例 增加 list.append(obj) 增加元素到末尾 eg. >>> list1=['hello','world','how','are','you' ...

  5. Windows添加.NET Framework 3.0 NetFx3 失败 - 状态为:0x800f0950

    原文链接:https://answers.microsoft.com/zh-hans/insider/forum/all/win10-dism%E9%94%99%E8%AF%AF-0x800f0950 ...

  6. GZip使用

    class Program { static void Main(string[] args) { //Trace.Listeners.Clear(); //Trace.Listeners.Add(n ...

  7. Confluence 6 编辑站点欢迎消息

    通过编辑欢迎信息能够为你站点的主页面添加一些个人信息. 站点的欢迎信息显示在站点主面板的右侧,这是你对站点添加声明,连接,有关你项目组美好回忆照片的完美位置. 你需要 Confluence 管理员权限 ...

  8. index_select ,clamp,detach

    1.torch.clamp(input,min,max,out=None)-> Tensor 将input中的元素限制在[min,max]范围内并返回一个Tensor 2.index_selec ...

  9. nginx实战(三)之静态资源web服务(跨站访问)

    语法 虽然说浏览器禁止跨站访问以防(CSRF),但出于一些原因还是要进行跨站访问,服务端通过设置头信息Access-Control-Allow-Orign:xxxx,客户端收到后就会允许跨站访问了 实 ...

  10. html超文本标记语言

     <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...