Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <cassert>
- #include <cstdio>
- #include <algorithm>
- #include <set>
- #include <math.h>
- #include <string>
- #include <map>
- #include <unordered_map>
- #include <unordered_set>
- #include <deque>
- #include <iomanip>
- #pragma GCC optimize(-Ofast)
- #define pr pair
- #define mp make_pair
- #define ft first
- #define sd second
- #define ll long long
- #define ld long double
- using namespace std;
- #ifdef FAST_ALLOCATOR_MEMORY
- int allocator_pos = 0;
- char allocator_memory[(int)FAST_ALLOCATOR_MEMORY];
- inline void* operator new (size_t n) {
- char* res = allocator_memory + allocator_pos;
- allocator_pos += n;
- assert(allocator_pos <= (int)FAST_ALLOCATOR_MEMORY);
- return (void*)res;
- }
- inline void operator delete (void*) noexcept { }
- //inline void * operator new [] ( size_t ) { assert(0); }
- //inline void operator delete [] ( void * ) { assert(0); }
- #endif
- inline int readUInt();
- inline int readChar();
- inline bool isEof();
- inline int getChar();
- static const int buf_size = 4096;
- static unsigned char buf[buf_size];
- static int buf_len = 0, buf_pos = 0;
- inline bool isEof() {
- if (buf_pos == buf_len) {
- buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
- if (buf_pos == buf_len)
- return 1;
- }
- return 0;
- }
- inline int getChar() {
- return isEof() ? -1 : buf[buf_pos++];
- }
- inline int readChar() {
- int c = getChar();
- while (c != -1 && c <= 32)
- c = getChar();
- return c;
- }
- inline int readUInt() {
- int c = readChar(), x = 0;
- while ('0' <= c && c <= '9')
- x = x * 10 + c - '0', c = getChar();
- return x;
- }
- inline int superRand() {
- if (RAND_MAX == (1 << 15) - 1) {
- return (rand() << 15) + rand();
- }
- return rand();
- }
- struct Node {
- int key, prior, sz;
- ll sum;
- Node* l, * r, * p;
- inline Node() {};
- inline Node(int key_) :
- l(nullptr),
- r(nullptr),
- prior(superRand()),
- sz(1),
- sum(key),
- key(key_)
- {};
- };
- typedef Node* Pnode;
- inline int get_size(Pnode root) {
- if (root != nullptr)
- return root->sz;
- return 0;
- }
- inline ll get_sum(Pnode root) {
- if (root != nullptr)
- return root->sum;
- else
- return 0;
- }
- inline void update(Pnode root) {
- if (root != nullptr) {
- root->sz = get_size(root->l) + get_size(root->r) + 1;
- root->sum = get_sum(root->l) + get_sum(root->r) + root->key;
- }
- }
- void forceupdate(Pnode root) {
- if (root->l != nullptr)
- forceupdate(root->l);
- if (root->r != nullptr)
- forceupdate(root->r);
- update(root);
- }
- void splitbykey(Pnode root, Pnode& l, Pnode& r, int x) {
- if (root == nullptr)
- return void(l = r = nullptr);
- if (root->key < x) {
- splitbykey(root->r, root->r, r, x);
- l = root;
- }
- else {
- splitbykey(root->l, l, root->l, x);
- r = root;
- }
- update(r);
- update(l);
- }
- void splitbysz(Pnode root, Pnode& l, Pnode& r, int k) {
- if (root == nullptr)
- return void(l = r = 0);
- if (get_size(root->l) >= k) {
- splitbysz(root->l, l, root->l, k);
- r = root;
- }
- else {
- splitbysz(root->r, root->r, r, k - get_size(root->l) - 1);
- l = root;
- }
- update(root);
- }
- void mymerge(Pnode& root, Pnode l, Pnode r) {
- if (!l || !r)
- return void(root = l ? l : r);
- if (l->prior > r->prior) {
- mymerge(l->r, l->r, r);
- root = l;
- }
- else {
- mymerge(r->l, l, r->l);
- root = r;
- }
- update(root);
- }
- inline void insert(Pnode root, Pnode ins) {
- Pnode l, r;
- splitbykey(root, l, r, ins->key);
- mymerge(root, l, ins);
- mymerge(root, root, r);
- }
- inline void erase(Pnode root, int x) {
- Pnode l, m, r;
- splitbykey(root, l, m, x);
- splitbysz(m, m, r, 1);
- mymerge(root, l, r);
- }
- int a[100000];
- Pnode trees[400228];
- vector<int> build1(int n, int l, int r) {
- vector<int> nodes;
- if (r - l == 1)
- nodes = { a[l] };
- else {
- int m = (l + r) / 2;
- vector<int> nodes1 = build1(2 * n + 1, l, m);
- vector<int> nodes2 = build1(2 * n + 2, m, r);
- nodes.resize(r - l);
- merge(nodes1.begin(), nodes1.end(), nodes2.begin(), nodes2.end(), nodes.begin());
- }
- trees[n] = new Node(0);
- trees[n]->prior = INT32_MAX;
- Pnode cur = trees[n];
- for (int i = 0; i < r - l; ++i) {
- Pnode newnode = new Node(nodes[i]);
- while (cur->prior < newnode->prior)
- cur = cur->p;
- newnode->l = cur->r;
- if (cur->r != nullptr)
- cur->r->p = newnode;
- cur->r = newnode;
- newnode->p = cur;
- cur = newnode;
- }
- forceupdate(trees[n]);
- return nodes;
- }
- int pos, oldval, newval;
- void change(int n, int l, int r) {
- erase(trees[n], oldval);
- insert(trees[n], new Node(newval));
- if (r - l != 1) {
- int m = (l + r) / 2;
- if (m <= pos)
- change(2 * n + 2, m, r);
- else
- change(2 * n + 1, l, m);
- }
- }
- int l1, r1, a1, b1;
- pair<ll, int> ask(int n, int l, int r) {
- if (l >= r1 || r <= l1)
- return mp(0, 0);
- if (l >= l1 && r <= r1) {
- pr<ll, int> ans;
- Pnode L, M, R;
- splitbykey(trees[n], L, M, a1);
- splitbykey(M, M, R, b1 + 1);
- ans.first = get_sum(M);
- ans.second = get_size(M);
- mymerge(M, M, R);
- mymerge(trees[n], L, M);
- return ans;
- }
- else {
- int m = (l + r) / 2;
- pr<ll, int> ans1 = ask(2 * n + 1, l, m), ans2 = ask(2 * n + 2, m, r);
- return mp(ans1.ft + ans2.ft, ans1.sd + ans2.sd);
- }
- }
- int main()
- {
- int n;
- //n = readUInt();
- cin >> n;
- srand(time(NULL));
- for (int i = 0; i < n; i++) {
- //a[i] = readUInt();
- cin >> a[i];
- }
- build1(0, 0, n);
- int q;
- //q = readUInt();
- cin >> q;
- cout << setprecision(20);
- short type;
- for (int i = 0; i < q; ++i) {
- cin >> type;
- //type = readUInt();
- if (type == 1) {
- /*l1 = readUInt();
- r1 = readUInt();
- a1 = readUInt();
- b1 = readUInt();*/
- cin >> l1 >> r1 >> a1 >> b1;
- --l1;
- auto ans = ask(0, 0, n);
- if (ans.second == 0)
- cout << 0 << ' ';
- else
- cout << (ld)ans.first / (ld)ans.second << ' ';
- }
- else {
- /*l1 = readUInt();
- r1 = readUInt();*/
- cin >> l1 >> r1;
- if (a[l1 - 1] != a[r1 - 1]) {
- pos = l1 - 1, oldval = a[l1 - 1], newval = a[r1 - 1];
- change(0, 0, n);
- pos = r1 - 1, oldval = a[r1 - 1], newval = a[l1 - 1];
- change(0, 0, n);
- swap(a[l1 - 1], a[r1 - 1]);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement