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. ubuntu Qt linuxdeployqt打包

    1.下载PatchELF 0.9.,https://nixos.org/patchelf.html 安装:./configure make sudo make install 2.终端命令设置设置环境 ...

  2. java使用RunTime调用windows命令行

    当Java需要调用windows系统进行交互时,可以使用Runtime进行操作. 例子: 1.调用window中获取关于java相关的进行信息 Runtime rt = Runtime.getRunt ...

  3. 查询每个分组中第N的一条记录

    查询每个分组中第N的一条记录 -- 天气表,每天每个地区采集了多条记录的天气信息,但是时间只记录到了天,导致同一个地区同一天出现了多条天气记录 -- 目的:获取所有地区在每天中第N的一条记录 sele ...

  4. Appium新版本不再支持ByName定位了怎么办

    appium版本在1.5以后就不再支持ByName的定位,本文章仅介绍在appium1.6.3/1.6.4/1.6.5版本下如何支持ByName定位,适用于安卓.在使用appium1.5之后的版本时, ...

  5. 布思算法——Java实现

    前面一篇提到二进制队列实现了 N位二进制的补码,那么我们来实现布思算法. 关于BinaryQueue:https://www.cnblogs.com/XT-xutao/p/10050518.html ...

  6. react.css

    /* KISSY CSS Reset 理念:清除和重置是紧密不可分的 特色:1.适应中文 2.基于最新主流浏览器 维护:玉伯(lifesinger@gmail.com), 正淳(ragecarrier ...

  7. 通过cmd 使用 InstallUtil.exe 命令 操作 windows服务 Windows Service

    要安装windows service 首先要找到 InstallUtil.exe,InstallUtil.exe位置在 C:\Windows\Microsoft.NET\Framework\v4.0. ...

  8. Confluence 6 Oracle 测试你的数据库连接

    在你的数据库设置界面,有一个 测试连接(Test connection)按钮可以检查: Confluence 可以连接你的数据库服务器 数据库的字符集编码是否正确 你的数据库用户是否具有需要的权限 你 ...

  9. Scala-IDE构建Maven项目

    本教程演示如何使用Scala-IDE构建一个Scala Maven项目. 1. 下载Scala IDE 通过以下链接下载Scala IDE: http://scala-ide.org/download ...

  10. MySQL外键使用详解

    一.基本概念 1.MySQL中“键”和“索引”的定义相同,所以外键和主键一样也是索引的一种.不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引.用于外键关系的字段必须 ...