• [BZOJ3337]ORZJRY I


    感觉写完这题神清气爽,本来认为平衡树已经属于很复杂的东西了。
    强烈推荐写一写这题,写完了就再也不用怕任何数据结构了。
    思路很简单,每个块内维护一个(s)数组与_s数组。
    表示原数组和排完序之后的数组,之后各种操作再打上各种标记。
    于是你就轻松愉快 的解决了这道题。
    代码:

    #include <bits/stdc++.h>
    #define il inline
    #define gc() getchar()
    #define pc putchar
    #define isd isdigit
    #define set _set
    #pragma GCC optimize(2) 
    #define max(x,y) (x > y ? x : y)
    #define min(x,y) (x < y ? x : y)
    const int INF  = 0x7f7f7f7f;
    const int _MAX = 1e3 + 10;
    const int MAXN = 1e4 + 10;
    typedef long long ll;
    using namespace std;    
    char buf[1<<21],*p1=buf,*p2=buf;
    int n,m,i,j,k,opt,bls;
    int sta[MAXN];
    queue<int> q;
    template<typename T> il void read(T& res) {
        res = 0;char c;bool sign = 0;
        for(c = gc();!isd(c);c = gc()) sign |= c == '-';
        for(;isd(c);c = gc()) res = (res << 1) + (res << 3) + (c ^ 48);
        res *= (sign) ? -1 : 1;
        return;
    }
    il int _abs(int x) {
        return x < 0 ? -x : x;
    }
    struct Node {
        int s[_MAX],_s[_MAX];
        int size,nxt,rev,add,same;
        ll sum;
        il void clear() {
            size = nxt = rev = add = same =  0;sum = 0ll;
            nxt = -1;
            memset(s,0,sizeof(s));
            memset(_s,0,sizeof(_s));
        }
    }t[MAXN]; 
    il void _swap(int& x,int& y) {
        x ^= y ^= x ^= y;
    }
    il int NewNode() {
        int res = q.front();q.pop();return res;
    }
    il void _del(int num) {
        q.push(num);t[num].clear();return;
    }
    il void get(int& N,int& now) {
        now = 0;
        while(t[now].nxt != -1 && N > t[now].size) {
            N -= t[now].size;
            now = t[now].nxt;
        }
        return;
    }
    il void up(int num) {
        if(t[num].rev) {
            t[num].rev = 0;
            for(int i = 1;i <= t[num].size / 2;i++) {
                _swap(t[num].s[i],t[num].s[t[num].size - i + 1]);
            }
        }
        if(t[num].same) {
            for(int i = 1;i <= t[num].size;i++) t[num].s[i] = t[num].same;
            t[num].sum = t[num].same * t[num].size;t[num].same = 0;
        }
        if(t[num].add) {
            for(int i = 1;i <= t[num].size;i++) t[num].s[i] += t[num].add;
            t[num].sum += t[num].add * t[num].size;t[num].add = 0;
        }
        return;
    }
    il void _set(int num) {
        t[num].sum = 0;
        for(int i = 1;i <= t[num].size;i++) {
            t[num].sum += t[num].s[i];t[num]._s[i] = t[num].s[i];
        }
        sort(t[num]._s + 1,t[num]._s + t[num].size + 1);
        return;
    }
    il void Merge(int num) {        
        int tmp = t[num].nxt;          
        up(num);up(tmp);
        for(int i = 1;i <= t[tmp].size;i++) {
            t[num].s[++t[num].size] = t[tmp].s[i];      
        }
        t[num].nxt = t[tmp].nxt;
        _del(tmp);set(num);
    }
    il void _Merge(int num) {
        int now = num;
        while(now != -1) {
            if(t[now].nxt != -1 && t[now].size + t[t[now].nxt].size <= bls) {
                Merge(now);
            }
            now = t[now].nxt;
        }   
        return;
    }
    il void divide(int num,int pos) {
        up(num);int tmp = NewNode();
        for(int i = pos;i <= t[num].size;i++) {
            t[tmp].s[++t[tmp].size] = t[num].s[i];
        }
        t[tmp].nxt = t[num].nxt;t[num].nxt = tmp;
        t[num].size = max(pos - 1,0);set(tmp);set(num);
    } 
    il void insert(int pos,int val) {
        int now;pos++;get(pos,now);divide(now,pos);
        t[now].s[++t[now].size] = val;
        set(now);_Merge(now);
    }
    il void _delete(int pos) {
        int now;get(pos,now);up(now);        
        for(int i = pos;i < t[now].size;i++) {
            t[now].s[i] = t[now].s[i + 1];      
        }                 
        t[now].size--;set(now);_Merge(now);
        return;
    }                                           
    il void orz(int l,int r,int& _l,int& _r) {
        int pos = l;get(pos,_l);divide(_l,pos);      
        pos = r + 1;get(pos,_r);divide(_r,pos);
        pos = r;get(pos,_r);return;
    }
    il void reverse(int l,int r) {
        int _l,_r;orz(l,r,_l,_r);
        int p = t[_l].nxt,top = 0;
        while(p != t[_r].nxt) {
            sta[++top] = p;t[p].rev ^= 1;p = t[p].nxt;
        }
        t[sta[1]].nxt = t[_r].nxt;
        for(int i = top;i > 1;i--) t[sta[i]].nxt = sta[i - 1];
        t[_l].nxt = _r;_Merge(_l);return;
    }
    il void move_kth(int x,int y,int z) {
        int _l,_r,p,_p;
        orz(x,y - z,_l,p);
        orz(y - z + 1,y,p,_r);
        _p = t[_l].nxt;
        t[_l].nxt = t[p].nxt;
        t[p].nxt  = t[_r].nxt;
        t[_r].nxt = _p;
        _Merge(_l);
        return; 
    }
    il void add(int x,int y,int z) {
        int l,r;orz(x,y,l,r);int p = t[l].nxt;
        while(p != t[r].nxt) {
            t[p].add += z;t[p].sum += z * t[p].size;
            p = t[p].nxt;
        }
        _Merge(l);
        return;
    }
    il void same(int x,int y,int z) {
        int l,r;orz(x,y,l,r);int p = t[l].nxt;
        while(p != t[r].nxt) {
            t[p].add = 0;t[p].same = z;t[p].sum = t[p].size * z;
            p = t[p].nxt;
        }
        _Merge(l);
        return;
    }
    il ll sum(int x,int y) {
        int l,r;orz(x,y,l,r);ll res = 0ll,p = t[l].nxt;
        while(p != t[r].nxt) res += t[p].sum,p = t[p].nxt;_Merge(l);
        return res;
    }
    il int range(int x,int y) {
        int l,r;orz(x,y,l,r);ll Max = -INF,Min = INF;int p = t[l].nxt;
        while(p != t[r].nxt) {
            if(t[p].size) {
                if(t[p].same) {
                    Max = max(Max,t[p].add + t[p].same);
                    Min = min(Min,t[p].add + t[p].same);         
                } else {                                   
                    Max = max(Max,t[p]._s[t[p].size] + t[p].add);
                    Min = min(Min,t[p]._s[1] + t[p].add);
                }
            }
            p = t[p].nxt;
        }   
        _Merge(l);return Max - Min;
    }
    il int near(int x,int y,int z) {
        int l,r;orz(x,y,l,r);int p = t[l].nxt,res = INF;
        while(p != t[r].nxt) {
            if(t[p].same) res = min(res,_abs(t[p].same + t[p].add - z));
            else {
                int tmp = lower_bound(t[p]._s + 1,t[p]._s + t[p].size + 1,z - t[p].add) - t[p]._s;
                if(tmp != t[p].size + 1) res = min(res,_abs(t[p]._s[tmp] + t[p].add - z));
                if(tmp != 1) tmp--,res = min(res,_abs(t[p]._s[tmp] + t[p].add - z)); 
            }
            p = t[p].nxt;
        }
        _Merge(l);return res;
    }
    il int Min_kth(int x,int y,int z) {
        int l,r;orz(x,y,l,r);int hl = 0,hr = 1e9,res;
        while(hl < hr) {
            int mid = (hl + hr) / 2 + 1,K = 1,p = t[l].nxt;
            while(p != t[r].nxt) {
                if(t[p].same) {
                    if(t[p].add + t[p].same < mid) K += t[p].size; 
                } else {
                    int x = upper_bound(t[p]._s + 1,t[p]._s + t[p].size + 1,mid - t[p].add - 1) - t[p]._s;
                    K += max(x - 1,0);
                }
                p = t[p].nxt;
            }
            if(K <= z) hl = mid;
            else hr = mid - 1;
        }
        _Merge(l);return hl;
    }
    il int qry_min(int x,int y,int z) {
        int l,r;orz(x,y,l,r);int res = 0,p = t[l].nxt;
        while(p != t[r].nxt) {
            if(t[p].same) {
                if(t[p].same + t[p].add < z) res += t[p].size;
            } else {
                int tmp = upper_bound(t[p]._s + 1,t[p]._s + t[p].size + 1,z - t[p].add - 1) - t[p]._s;
                res += max(tmp - 1,0);
            }
            p = t[p].nxt;
        }
        _Merge(l);return res;
    }
    int main() {
    //  freopen("std1.in","r",stdin);
    //  freopen("my1.out","w",stdout);
        read(n);bls = sqrt(n);
        for(int i = 1;i < 10000;i++) q.push(i);t[0].nxt = -1;t[0].size = 0;
        for(int i = 1;i <= n;i++) {
            int x;read(x);insert(i - 1,x);
        }   
        read(m);
        for(int i = 1,x,y,k;i <= m;i++) {
            int opt;read(opt);
            switch(opt) {
                case 1: {read(x);read(y);insert(x,y);break;}
                case 2: {read(x);_delete(x);break;}
                case 3: {read(x);read(y);reverse(x,y);break;}
                case 4: {read(x);read(y);read(k);move_kth(x,y,k);break;}
                case 5: {read(x);read(y);read(k);add(x,y,k);break;}
                case 6: {read(x);read(y);read(k);same(x,y,k);break;}
                case 7: {read(x);read(y);printf("%lld
    ",sum(x,y));break;}  
                case 8: {read(x);read(y);printf("%d
    ",range(x,y));break;}
                case 9: {read(x);read(y);read(k);printf("%d
    ",near(x,y,k));break;}
                case 10: {read(x);read(y);read(k);printf("%d
    ",Min_kth(x,y,k));break;}
                case 11: {read(x);read(y);read(k);printf("%d
    ",qry_min(x,y,k));break;}     
            }
        }
        return 0;
    }
    
  • 相关阅读:
    守护线程Daemon的理解
    Activity并行网关和排他网关
    Activity快速入门理解
    java虚拟机内存区域理解
    Maven的使用
    Mybatis拦截器(插件实现原理)
    網絡上好的博客收集
    jdbc 设置连接支持多条sql
    python 多环境安装
    Linux 系统命令
  • 原文地址:https://www.cnblogs.com/Sai0511/p/10459267.html
Copyright © 2020-2023  润新知