Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize("Ofast")
- #pragma GCC target("avx,avx2,fma")
- #include<bits/stdc++.h>
- #define F first
- #define S second
- #define vec vector
- #define pb push_back
- #define pll pair<ll, ll>
- #define pdd pair<ld, ld>
- #define umap unordered_map
- #define uset unordered_set
- #define pii pair<int, int>
- #define pnn pair<Node*, Node*>
- #define all(m) m.begin(), m.end()
- #define uid uniform_int_distribution
- #define init(m, x) memset(m, x, sizeof(m));
- #define FILE ifstream in("input.txt"); ofstream out("output.txt");
- #define fast cin.tie(0); cout.tie(0); cin.sync_with_stdio(0); cout.sync_with_stdio(0);
- using namespace std;
- typedef string str;
- typedef long long ll;
- typedef long double ld;
- typedef unsigned int uint;
- typedef unsigned long long ull;
- mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
- struct Node{
- Node *l = 0, *r = 0;
- int x, y, sz, e;
- Node(){}
- Node(int a){
- x = e = a;
- y = rnd();
- sz = 1;
- }
- };
- int gsz(Node *n){return n ? n->sz : 0;}
- int ge(Node *n){return n ? n->e : 0;}
- void upd(Node *n){
- if(!n) return;
- n->sz = gsz(n->l) + 1 + gsz(n->r);
- n->e = ge(n->l) + n->x + ge(n->r);
- }
- Node* merge(Node *l, Node *r){
- if(!l) return r;
- if(!r) return l;
- if(l->y > r->y){
- l->r = merge(l->r, r); upd(l);
- return l;
- }
- r->l = merge(l, r->l); upd(r);
- return r;
- }
- pnn splitSz(Node *n, int k){
- if(!n) return {0,0};
- if(k<=gsz(n->l)){
- pnn p = splitSz(n->l, k);
- n->l = p.S; upd(n);
- p.S = n;
- return p;
- }
- pnn p = splitSz(n->r, k-gsz(n->l)-1);
- n->r = p.F; upd(n);
- p.F = n;
- return p;
- }
- const int G = 15001; //!!!!!!!!!!!1
- int a, b, z;
- int kek[G*2+5], m[G], n[G];
- void print(Node *n, int ps){
- if(!n) return;
- print(n->l, ps);
- for(int q=0; q<n->x; q++) cout<<kek[ps]<<" ";
- //for(int q=0; q<n->x; q++) cout<<ps+gsz(n->l)+1<<" ";
- print(n->r, ps+gsz(n->l)+1);
- }
- void compress(){
- for(int q=0; q<a; q++) kek[q] = m[q];
- for(int q=0; q<b; q++) kek[a+q] = n[q];
- inplace_merge(kek, kek+a, kek+a+b);
- for(int q=0; q<a; q++) m[q] = lower_bound(kek, kek+a+b, m[q]) - kek;
- for(int q=0; q<b; q++) n[q] = lower_bound(kek, kek+a+b, n[q]) - kek;
- }
- void add_to_pos(Node *n, int ps, int val){ // 1 - index
- if(!n) return;
- if(ps == gsz(n->l)+1) n->x += val, n->e += val;
- else if(ps < gsz(n->l)+1) add_to_pos(n->l, ps, val);
- else add_to_pos(n->r, ps-gsz(n->l)-1, val);
- upd(n);
- }
- Node* build(int l, int r){
- if(l>r) return 0;
- int md = (l+r)>>1;
- Node *res = new Node(0);
- res->l = build(l, md-1);
- res->r = build(md+1, r);
- upd(res);
- return res;
- }
- pair<int, pii> wtf(Node *n, int k, int c = 1){ //1 - index
- assert(n);
- if(ge(n->l)<k && k<=ge(n->l)+n->x){
- return {c+gsz(n->l), {k-ge(n->l), n->x}};
- }
- if(k<=ge(n->l)) return wtf(n->l, k, c);
- return wtf(n->r, k-ge(n->l)-n->x, c+gsz(n->l)+1);
- }
- pnn smart_merge(Node *l, Node *r){
- int sz = gsz(l);
- if(sz==1){
- r->x += l->x; r->e += l->x;
- l->x = l->e = 0;
- return {l, r};
- }
- if(ge(l)==0) return {l, r};
- if(ge(r)==0) return {r, l};
- pnn p1 = splitSz(l, sz/2);
- pnn p2 = splitSz(r, sz/2);
- pnn d1 = smart_merge(p1.F, p2.F);
- pnn d2 = smart_merge(p1.S, p2.S);
- return {merge(d1.F, d2.F), merge(d1.S, d2.S)};
- }
- int main() {
- fast;
- cin>>a; for(int q=0; q<a; q++) cin>>m[q];
- cin>>b; for(int q=0; q<b; q++) cin>>n[q];
- compress();
- Node *M = build(1, G*2), *N = build(1, G*2);
- for(int q=0; q<a; q++) add_to_pos(M, m[q]+1, 1);
- for(int q=0; q<b; q++) add_to_pos(N, n[q]+1, 1);
- cin>>z;
- int t, l, r, d;
- for(; z--; ){
- cin>>t>>l>>r; d = r-l+1;
- if(t==2) swap(M, N);
- assert(ge(M)>=r);
- pair<int, pii> p1 = wtf(M, l);
- pair<int, pii> p2 = wtf(M, r);
- if(p1.F==p2.F){
- add_to_pos(N, p1.F, d);
- add_to_pos(M, p1.F, -d);
- if(t==2) swap(M, N);
- continue;
- }
- add_to_pos(N, p1.F, p1.S.S-p1.S.F+1);
- add_to_pos(M, p1.F, -(p1.S.S-p1.S.F+1));
- add_to_pos(N, p2.F, p2.S.F);
- add_to_pos(M, p2.F, -p2.S.F);
- l = p1.F+1, r = p2.F-1;
- if(l>r){if(t==2) swap(M, N);continue;}
- pnn m1 = splitSz(M, l-1), m2 = splitSz(m1.S, r-l+1);
- pnn n1 = splitSz(N, l-1), n2 = splitSz(n1.S, r-l+1);
- pnn mid = smart_merge(m2.F, n2.F);
- M = merge(merge(m1.F, mid.F), m2.S);
- N = merge(merge(n1.F, mid.S), n2.S);
- if(t==2) swap(M, N);
- }
- cout<<ge(M)<<endl; print(M, 0); cout<<endl;
- cout<<ge(N)<<endl; print(N, 0); cout<<endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment