• 【洛谷】P4883 mzf的考验


    【洛谷】P4883 mzf的考验

    最近忽然放弃治疗开始随机跳题了

    感觉还行

    就是必须吸氧感觉有点糟糕。。。

    这题翻转和求和都是平衡树基本操作,那个异或可以通过维护树中(2)进制下第(2^{i})位的(1)的个数,即可(O(log d))快速维护

    当敲板子玩了

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define ba 47
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    mt19937 rnd(20020328); 
    struct node {
        int pri;
        int lc,rc,siz;
        int cnt[20],d;
        int64 sum,val;
        bool rev;
    }tr[MAXN];
    int N,M,rt;
    int a[MAXN];
    #define lc(u) tr[u].lc
    #define rc(u) tr[u].rc
    #define sum(u) tr[u].sum
    void update(int u) {
        for(int j = 0 ; j < 20 ; ++j) {
    	tr[u].cnt[j] = ((tr[u].val >> j) & 1) + tr[lc(u)].cnt[j] + tr[rc(u)].cnt[j];
        }
        tr[u].sum = tr[u].val + tr[lc(u)].sum + tr[rc(u)].sum;
        tr[u].siz = 1 + tr[lc(u)].siz + tr[rc(u)].siz;
    }
    void xorit(int u,int d) {
        tr[u].val ^= d;tr[u].d ^= d;
        for(int j = 0 ; j < 20 ; ++j) {
    	if(d >> j & 1) {
    	    tr[u].sum -= 1LL * tr[u].cnt[j] * (1 << j);
    	    tr[u].sum += 1LL * (tr[u].siz - tr[u].cnt[j]) * (1 << j);
    	    tr[u].cnt[j] = tr[u].siz - tr[u].cnt[j]; 
    	}
        }
        
    }
    void Rev(int u) {
        tr[u].rev ^= 1;
        swap(lc(u),rc(u));
    }
    void pushdown(int u) {
        if(tr[u].d) {
    	if(lc(u)) xorit(lc(u),tr[u].d);
    	if(rc(u)) xorit(rc(u),tr[u].d);
    	tr[u].d = 0;
        }
        if(tr[u].rev) {
    	if(lc(u)) Rev(lc(u));
    	if(rc(u)) Rev(rc(u));
    	tr[u].rev = 0;
        }
    }
    int Merge(int u,int v) {
        if(!u) return v;
        if(!v) return u;
        pushdown(u);pushdown(v);
        if(tr[u].pri > tr[v].pri) {
    	tr[u].rc = Merge(tr[u].rc,v);
    	update(u);
    	return u;
        }
        else {
    	tr[v].lc = Merge(u,tr[v].lc);
    	update(v);
    	return v;
        }
    }
    void Split(int u,int &L,int &R,int s) {
        if(u == 0) {L = R = 0;return;}
        int t = tr[lc(u)].siz + 1;
        pushdown(u);
        if(s >= t) {
    	L = u;
    	Split(tr[u].rc,tr[L].rc,R,s - t);
    	update(L);
        }
        else {
    	R = u;
    	Split(tr[u].lc,L,tr[R].lc,s);
    	update(R);
        }
    }
    void Modify(int l,int r,int d) {
        int L,R,p;
        Split(rt,L,R,l - 1);
        Split(R,p,R,r - l + 1);
        xorit(p,d);
        rt = Merge(L,p);rt = Merge(rt,R);
    }
    void Rev_Range(int l,int r) {
        int L,R,p;
        Split(rt,L,R,l - 1);
        Split(R,p,R,r - l + 1);
        Rev(p);
        rt = Merge(L,p);rt = Merge(rt,R);
    }
    int64 Query(int l,int r) {
        int L,R,p;
        Split(rt,L,R,l - 1);
        Split(R,p,R,r - l + 1);
        int64 res = tr[p].sum;
        rt = Merge(L,p);rt = Merge(rt,R);
        return res;
    }
    
    void Solve() {
        read(N);read(M);
        for(int i = 1 ; i <= N ; ++i) {
    	read(a[i]);
    	tr[i].pri = rnd();tr[i].sum = a[i];tr[i].val = a[i];
    	for(int j = 0 ; j < 20 ; ++j) {
    	    tr[i].cnt[j] = (a[i] >> j) & 1;
    	}
    	tr[i].siz = 1;
    	rt = Merge(rt,i);
        }
        int opt,l,r,d;
        for(int i = 1 ; i <= M ; ++i) {
    	read(opt);read(l);read(r);
    	if(opt == 1) Rev_Range(l,r);
    	else if(opt == 2) {read(d);Modify(l,r,d);}
    	else {out(Query(l,r));enter;}
        }
    }
    int main(){
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
    
        Solve();
    }
    
  • 相关阅读:
    centos6.4下搭建Lampp
    lampp环境部署bugfree3.0.4
    ftp使用踩坑
    redis故障处理
    程序设计语言发展回顾与展望
    那些相见恨晚的 JavaScript 技巧
    我的七个建议
    让UNION与ORDER BY并存于SQL语句当中
    使用SQL语句创建登录名,并为指定数据库分配制定权限
    Linux操作系统菜鸟变成高手的十个建议
  • 原文地址:https://www.cnblogs.com/ivorysi/p/11007511.html
Copyright © 2020-2023  润新知