Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <math.h>
- #include <map>
- #include <vector>
- #include <set>
- #include <deque>
- #include <algorithm>
- #include <list>
- using namespace std;
- #ifdef LOCAL
- #include <fstream>
- ifstream cin("tests.txt");
- ofstream cout("output1.txt");
- #else // LOCAL
- #include <iostream>
- #endif
- #define ull unsigned long long
- #define ll long long
- #define pii pair<int,int>
- #define DEBUG false
- #define CHECKER false
- struct block {
- deque<int> data;
- bool rev;
- int val;
- block(int val = -1,bool rev = false) {
- this->rev = rev;
- this->val = val;
- }
- int get_less(int x) {
- if(this->val != -1)
- if(this->val >= x)
- return data.size();
- else
- return 0;
- int ans = this->data.size() - (lower_bound(this->data.begin(), this->data.end(), x) - this->data.begin());
- return ans;
- }
- void add_element(int x,bool to_l = false) {
- to_l ^= this->rev;
- if(to_l)
- this->data.push_front(x);
- else
- this->data.push_back(x);
- }
- pair<block,block> split(int pos) {
- //without the pos element
- if(this->rev==true) {
- pos = this->data.size()-pos-1;
- }
- block lb;
- for(int i = 0; i < pos; i++) {
- lb.add_element(this->data[i]);
- }
- block rb;
- for(int i = pos+1; i < this->data.size(); i++) {
- rb.add_element(this->data[i]);
- }
- if(this->rev) {
- swap(lb,rb);
- lb.rev = true;
- rb.rev = true;
- }
- lb.val = this->val;
- rb.val = this->val;
- return {lb,rb};
- }
- int get_el(int pos) {
- if(this->rev==true) {
- pos = this->data.size()-pos-1;
- }
- return this->data[pos];
- }
- };
- list<block> sqr;
- void coutsqr();
- void set_val(int l,int r,int x) {
- int sl = 0;
- int sr = -1;
- bool dbg = false;
- if(DEBUG && l==4&&r==4&&x==74209) {
- cout << "\n____________IN_SET___\n";
- coutsqr();
- int klsdjfsd = 123;
- dbg = true;
- }
- for(auto i = sqr.begin(); i!= sqr.end(); i++) {
- block & curblock = *i;
- if(curblock.data.size()==0)
- continue;
- sl = sr+1;
- sr = sl + curblock.data.size()-1;
- if(sr<sl)
- continue;
- if(sr < l)
- continue;
- if(sl > r)
- continue;
- if(l <= sl && sr <= r) {
- curblock.val = x;
- continue;
- }
- if(sl<=l && l<=sr && sl<=r && r<=sr) {
- pair<block,block> blocks1 = curblock.split(l-sl);
- block & lb1 = blocks1.first;
- block & rb1 = blocks1.second;
- rb1.add_element(curblock.get_el(l-sl),true);
- sl = sl + lb1.data.size();
- pair<block,block> blocks2 = rb1.split(r-sl);
- block & lb2 = blocks2.first;
- block & rb2 = blocks2.second;
- lb2.add_element(rb1.get_el(r-sl));
- lb2.val = x;
- if(dbg) {
- cout << "\ncurblock:\n";
- for(auto j:curblock.data)
- cout << j << ' ';
- cout << "\nlb1:\n";
- for(auto j:lb1.data)
- cout << j << ' ';
- cout << "\nrb1:\n";
- for(auto j:rb1.data)
- cout << j << ' ';
- cout << "\nlb2:\n";
- for(auto j:lb2.data)
- cout << j << ' ';
- cout << "\nrb2:\n";
- for(auto j:rb2.data)
- cout << j << ' ';
- }
- i = sqr.erase(i);
- sqr.insert(i,lb1);
- sqr.insert(i,lb2);
- sqr.insert(i,rb2);
- break;
- }
- if(sl<=l && l<=sr) {
- pair<block,block> blocks = curblock.split(l-sl);
- block & lb = blocks.first;
- block & rb = blocks.second;
- rb.add_element(curblock.get_el(l-sl),true);
- rb.val = x;
- i = sqr.erase(i);
- sqr.insert(i,lb);
- sqr.insert(i,rb);
- i--;
- i--;
- sr = sl + lb.data.size()-1;
- continue;
- }
- if(sl<=r && r<=sr) {
- pair<block,block> blocks = curblock.split(r-sl);
- block & lb = blocks.first;
- block & rb = blocks.second;
- lb.add_element(curblock.get_el(r-sl));
- lb.val = x;
- i = sqr.erase(i);
- sqr.insert(i,lb);
- sqr.insert(i,rb);
- i--;
- i--;
- continue;
- }
- }
- }
- int get_val(int l,int r,int x) {
- if(DEBUG && l==6&&r==6)
- int skladjfds = 2;
- int sl = 0;
- int sr = -1;
- int ans = 0;
- for(auto i = sqr.begin(); i!= sqr.end(); i++) {
- block & curblock = *i;
- if(curblock.data.size()==0)
- continue;
- sl = sr+1;
- sr = sl + curblock.data.size()-1;
- if(sr<sl)
- continue;
- if(sr < l)
- continue;
- if(sl > r)
- continue;
- if(l <= sl && sr <= r) {
- ans += curblock.get_less(x);
- continue;
- }
- if(sl<=l && l<=sr && sl<=r && r<=sr) {
- pair<block,block> blocks1 = curblock.split(l-sl);
- block & lb1 = blocks1.first;
- block & rb1 = blocks1.second;
- rb1.add_element(curblock.get_el(l-sl),true);
- sl = sl + lb1.data.size();
- pair<block,block> blocks2 = rb1.split(r-sl);
- block & lb2 = blocks2.first;
- block & rb2 = blocks2.second;
- lb2.add_element(rb1.get_el(r-sl));
- ans += lb2.get_less(x);
- break;
- }
- if(sl<=l && l<=sr) {
- pair<block,block> blocks = curblock.split(l-sl);
- block & lb = blocks.first;
- block & rb = blocks.second;
- rb.add_element(curblock.get_el(l-sl),true);
- ans += rb.get_less(x);
- continue;
- }
- if(sl<=r && r<=sr) {
- pair<block,block> blocks = curblock.split(r-sl);
- block & lb = blocks.first;
- block & rb = blocks.second;
- lb.add_element(curblock.get_el(r-sl));
- ans += lb.get_less(x);
- continue;
- }
- }
- return ans;
- }
- void rreverse(int l,int r) {
- int sl = 0;
- int sr = -1;
- if(DEBUG && l==1&&r==1) {
- cout << "\n____________IN_REVERSE___\n";
- coutsqr();
- int klsdjfsd = 123;
- }
- vector <block *> vect;
- auto first_it = sqr.end();
- bool first_it_b = true;
- auto last_it = sqr.end();
- for(auto i = sqr.begin(); i!= sqr.end(); i++) {
- block & curblock = *i;
- if(curblock.data.size()==0)
- continue;
- sl = sr+1;
- sr = sl + curblock.data.size()-1;
- if(sr<sl)
- continue;
- if(sr < l)
- continue;
- if(sl > r)
- continue;
- if(sl<=l && l<=sr && sl<=r && r<=sr) {
- pair<block,block> blocks1 = curblock.split(l-sl);
- block & lb1 = blocks1.first;
- block & rb1 = blocks1.second;
- rb1.add_element(curblock.get_el(l-sl),true);
- sl = sl + lb1.data.size();
- pair<block,block> blocks2 = rb1.split(r-sl);
- block & lb2 = blocks2.first;
- block & rb2 = blocks2.second;
- lb2.add_element(rb1.get_el(r-sl));
- lb2.rev ^= 1;
- i = sqr.erase(i);
- sqr.insert(i,lb1);
- sqr.insert(i,lb2);
- sqr.insert(i,rb2);
- break;
- }
- if(l <= sl && sr <= r) {
- curblock.rev ^= 1;
- if(first_it_b) {
- first_it_b = false;
- first_it = i;
- }
- last_it = i;
- continue;
- }
- if(sl<=l && l<=sr) {
- pair<block,block> blocks = curblock.split(l-sl);
- block & lb = blocks.first;
- block & rb = blocks.second;
- //DEBUG
- // cout << "\n-----START_DEBUG\nlb:\n";
- // for(auto i:lb.data)
- // cout << i << ' ';
- // cout << "\nrb\n";
- // for(auto i:rb.data)
- // cout << i << ' ';
- // cout << "\n-----END_DEBUG\n\n";
- //exit(0);
- rb.add_element(curblock.get_el(l-sl),true);
- i = sqr.erase(i);
- sqr.insert(i,lb);
- sqr.insert(i,rb);
- i--;
- i--;
- sr = sl + lb.data.size()-1;
- continue;
- }
- if(sl<=r && r<=sr) {
- pair<block,block> blocks = curblock.split(r-sl);
- block & lb = blocks.first;
- block & rb = blocks.second;
- lb.add_element(curblock.get_el(r-sl));
- i = sqr.erase(i);
- lb.rev ^= 1;
- sqr.insert(i,lb);
- sqr.insert(i,rb);
- i--;
- i--;
- last_it = i;
- continue;
- }
- }
- // cout << "\n\n\n___AFTER_REVERSE\n";
- // coutsqr();
- // cout << "\n___AFTER_REVERSE\n\n\n";
- reverse(first_it,++last_it);
- }
- void build(vector<int> & a) {
- int curr = 0;
- int ss = sqrt(a.size());
- for(int i = 0; i < ss; i++) {
- block curblock;
- for(int j = 0; j < ss; j++) {
- curblock.add_element(a[curr++]);
- }
- sqr.push_back(curblock);
- }
- if(curr!=a.size()) {
- block curblock;
- while(curr != a.size()) {
- curblock.add_element(a[curr++]);
- }
- sqr.push_back(curblock);
- }
- }
- void coutsqr() {
- for(auto i:sqr) {
- for(auto j:i.data) {
- cout << j << ' ';
- }
- cout << " == " << i.val;
- cout << " == " << i.rev;
- cout << '\n';
- }
- }
- struct to_face {
- vector<int> a;
- to_face(vector<int> a) {
- this->a = a;
- }
- void sset(int l,int r, int x) {
- for(int i = l; i <=r; i++) {
- this->a[i] = x;
- }
- }
- void rreverse(int l,int r) {
- reverse(a.begin()+l,a.begin()+r+1);
- }
- int gget(int l, int r, int x) {
- int ans = 0;
- for(int i = l; i <=r; i++) {
- if(this->a[i] >= x)
- ans++;
- }
- return ans;
- }
- };
- to_face facer({0});
- void rebuild() {
- if(DEBUG){
- cout << "\n\n\n";
- coutsqr();
- }
- vector<int> a;
- for(auto i:sqr) {
- if(i.data.size()==0)
- continue;
- if(i.val != -1)
- for(int t = 0; t < i.data.size(); t++)
- a.push_back(i.val);
- else {
- if(i.rev)
- reverse(i.data.begin(),i.data.end());
- for(auto j:i.data) {
- a.push_back(j);
- }
- }
- }
- sqr.clear();
- build(a);
- if(DEBUG){
- cout << "\n\n\n";
- coutsqr();
- cout << "\n\n\n\n";
- for(auto &i:facer.a) {
- cout << i << " ";
- }
- cout << "\n\n\n";
- }
- }
- bool checker() {
- vector<int> a;
- //cout << "CHECKER_WORKING:\n";
- for(auto i:sqr) {
- if(i.data.size()==0)
- continue;
- if(i.val != -1)
- for(int t = 0; t < i.data.size(); t++) {
- if(DEBUG){
- cout << "PUSHED_TO_A: " << i.val;
- cout << "\n";
- }
- a.push_back(i.val);
- }
- else {
- if(i.rev)
- for(int j = i.data.size()-1; j>=0; j--) {
- if(DEBUG){
- cout << "PUSHED_TO_A: " << i.data[j];
- cout << "\n";
- }
- a.push_back(i.data[j]);
- } else
- for(auto j:i.data) {
- if(DEBUG){
- cout << "PUSHED_TO_A: " << j;
- cout << "\n";
- }
- a.push_back(j);
- }
- }
- }
- for(int i = 0; i < a.size(); i++) {
- if(a[i] != facer.a[i]) {
- {
- cout << "\n\n__ERROR__\n\na:\n";
- for(auto &i:a)
- cout << i << ' ';
- cout << "\nFACER:\n";
- for(auto i:facer.a)
- cout << i << ' ';
- cout << "\nFASTER:\n";
- coutsqr();
- cout << "\n\n";
- exit(0);
- }
- }
- }
- }
- int main() {
- //#define int long long
- int n;
- cin >> n;
- vector<int> a(n);
- for(auto &i:a)
- cin >> i;
- // to_face facer({0});
- if(DEBUG || CHECKER)
- facer = to_face(a);
- build(a);
- int t;
- cin >> t;
- int sqqq = sqrt(t);
- while(t--) {
- string s="\n";
- cin >> s;
- //cout <<s << ' ' << s.size() << endl;
- if(s=="get") {
- int l,r,x;
- cin >> l >> r >> x;
- int fast_ans = get_val(--l,--r,x);
- int fc_ans;
- if(DEBUG)
- fc_ans = facer.gget(l,r,x);
- cout << fast_ans << '\n';
- if(DEBUG)
- if(fast_ans!=fc_ans) {
- cout << "\n\n__ERROR__\n\n";
- cout << "get " << l << ' ' << r << ' ' << x << " ZAPROS " << t << "\n";
- cout << fast_ans << " " << fc_ans << "\n\n";
- cout << "FACER:\n";
- for(auto i:facer.a)
- cout << i << ' ';
- cout << "\nFASTER:\n";
- coutsqr();
- cout << "\n\n";
- exit(0);
- }
- }
- if(s=="set") {
- int l,r,val;
- cin >> l >> r >> val;
- set_val(--l,--r,val);
- if(CHECKER){
- facer.sset(l,r,val);
- checker();
- }
- if(DEBUG) {
- facer.sset(l,r,val);
- cout << "set " << l << ' ' << r << ' ' << val;
- cout << '\n';
- checker();
- }
- }
- if(s=="reverse") {
- int l,r;
- cin >> l >> r;
- //coutsqr();
- //cout << "\n\n\n\n";
- rreverse(--l,--r);
- if(CHECKER){
- facer.rreverse(l,r);
- checker();
- }
- if(DEBUG) {
- cout << "\n\nREVERSE " << l << ' ' << r;
- if(l==1 && r == 1) {
- cout << "\n";
- coutsqr();
- cout << "\n\n\n\n";
- }
- facer.rreverse(l,r);
- if(l==2 && r == 7) {
- coutsqr();
- cout << "\n\n\n\n";
- }
- cout << '\n';
- checker();
- }
- //coutsqr();
- //cout << "\n\n\n\n";
- }
- if(t%sqqq==0)
- rebuild();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement