Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <iostream>
- #include <fstream>
- #include <cmath>
- #include <algorithm>
- #include <ctime>
- #include <cctype>
- #include <cstdlib>
- #include <cassert>
- #include <functional>
- #include <iomanip>
- #include <string>
- #include <cstring>
- #include <map>
- #include <set>
- #include <vector>
- #define eps 1e-9
- #define inf int(1e9)
- #define inflong (long long)(1e18)
- #define forn(i, x, y) for (int i = (x); i <= (y); i++)
- #define ford(i, y, x) for (int i = (y); i >= (x); i--)
- #define sqr(a) ((a) * (a))
- #define abs(a) (((a) < 0) ? -(a) : (a))
- #define sz(a) (int)a.size()
- #define all(a) (a).begin(), (a).end()
- #define zero(a) memset(a, 0, sizeof(a))
- #define fst first
- #define snd second
- #define y1 osrughosduvgarligybakrybrogvba
- #define y0 aosfigdalrowgyalsouvgrlvygalri
- #define mp make_pair
- #define pb push_back
- #define taskname "reverse"
- using namespace std;
- typedef long long LL;
- typedef long double LD;
- typedef vector <int> vi;
- typedef vector <bool> vb;
- typedef vector <LL> vl;
- typedef pair<int, int> pii;
- const int MaxN = int(2e5);
- const LD pi = 3.1415926535897932384626433832795;
- struct node
- {
- int l, r;
- int x, y;
- int size;
- int mini;
- bool rev;
- node() {}
- };
- int n, q;
- int a[MaxN];
- node Tree[MaxN * 4];
- int now = 1, root = 0;
- int get(int p)
- {
- return p ? Tree[p].size : 0;
- }
- /*void swap(node &a, node &b)
- {
- swap(a.l, b.l);
- swap(a.r, b.r);
- swap(a.size, b.size);
- swap(a.x, b.x);
- swap(a.y, b.y);
- swap(a.mini, b.mini);
- swap(a.rev, b.rev);
- }*/
- void push(int p)
- {
- if (!p || !Tree[p].rev)
- return;
- Tree[p].rev = false;
- swap(Tree[p].l, Tree[p].r);
- if (Tree[p].l)
- Tree[Tree[p].l].rev ^= true;
- if (Tree[p].r)
- Tree[Tree[p].r].rev ^= true;
- }
- void update_size(int p)
- {
- push(p);
- if (!p)
- return;
- Tree[p].size = 1 + get(Tree[p].l) + get(Tree[p].r);
- Tree[p].mini = min(Tree[p].x, min(Tree[Tree[p].l].mini, Tree[Tree[p].r].mini));
- }
- int merge(int L, int R)
- {
- push(L);
- push(R);
- if (!L)
- return R;
- if (!R)
- return L;
- if (Tree[L].y < Tree[R].y)
- {
- int ans = merge(Tree[L].r, R);
- Tree[L].r = ans;
- update_size(L);
- return L;
- }
- else
- {
- int ans = merge(L, Tree[R].l);
- Tree[R].l = ans;
- update_size(R);
- return R;
- }
- return 0;
- }
- pii split(int p, int pos)
- {
- if (!p)
- return mp(0, 0);
- push(p);
- if (Tree[Tree[p].l].size < pos)
- {
- pii tmp = split(Tree[p].r, pos);
- Tree[p].r = tmp.fst;
- update_size(p);
- return mp(p, tmp.snd);
- }
- else
- {
- pii tmp = split(Tree[p].l, pos - 1 - Tree[Tree[p].l].size);
- Tree[p].l = tmp.snd;
- update_size(p);
- return mp(tmp.fst, p);
- }
- return mp(0, 0);
- }
- int CreateNode(int x)
- {
- Tree[now].size = 1;
- Tree[now].rev = false;
- Tree[now].x = x;
- Tree[now].y = rand();
- Tree[now].l = Tree[now].r = 0;
- Tree[now].mini = x;
- return now++;
- }
- void insert(int p, int pos, int y)
- {
- push(p);
- pii tmp = split(p, pos);
- root = merge(merge(tmp.fst, CreateNode(y)), tmp.snd);
- }
- int get_min(int p, int x, int y)
- {
- push(p);
- if (y <= 0 || x > Tree[p].size)
- return inf;
- if (x <= 1 && y >= Tree[p].size)
- return Tree[p].mini;
- int res = min(get_min(Tree[p].l, x, y), get_min(Tree[p].r, x - Tree[Tree[p].l].size - 1, y - Tree[Tree[p].l].size - 1));
- if (x <= Tree[Tree[p].l].size + 1 && y >= Tree[Tree[p].l].size + 1)
- return min(Tree[p].x, res);
- return res;
- }
- void reverse_segment(int p, int l, int r)
- {
- push(p);
- pii t1 = split(p, l);
- pii t2 = split(t1.snd, r - l + 1);
- Tree[t2.fst].rev ^= true;
- push(t2.fst);
- root = merge(merge(t1.fst, t2.fst), t2.snd);
- }
- void print(int p)
- {
- if (!p)
- return;
- print(Tree[p].l);
- printf("%d ", p);
- print(Tree[p].r);
- }
- int main()
- {
- freopen(taskname".in", "r", stdin);
- freopen(taskname".out", "w", stdout);
- srand(time(NULL));
- while (scanf("%d%d", &n, &q) >= 1)
- {
- Tree[0].l = Tree[0].r = Tree[0].size = 0;
- Tree[0].mini = inf;
- Tree[0].y = rand();
- Tree[0].rev = false;
- root = 0;
- now = 1;
- forn(i, 1, n)
- {
- scanf("%d", &a[i]);
- insert(root, i, a[i]);
- }
- forn(i, 0, q - 1)
- {
- int type, l, r;
- scanf("%d%d%d", &type, &l, &r);
- assert(type >= 1 && type <= 2);
- if (type == 1)
- reverse_segment(root, l, r);
- else
- printf("%d\n", get_min(root, l, r));
- }
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment