玄关,线段树求卡常
  • 板块灌水区
  • 楼主littlep001
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/2 10:19
  • 上次更新2024/10/2 13:12:26
查看原帖
玄关,线段树求卡常
922855
littlep001楼主2024/10/2 10:19
#include <iostream>
#include <vector>

using namespace std;
class fastIO{private:char ibuf[50007],*p1=ibuf,*p2=ibuf,obuf[50007],*p3=obuf,sta[50];bool file_end=false;char get(){return p1==p2&&(p2=(p1=ibuf)+fread(ibuf,1,50007,stdin),p1==p2)?(file_end=true),char(EOF):*p1++;}void put(const char x){p3-obuf<50007?*p3++=x:(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x);}public:explicit operator bool(){return!file_end;}size_t flush(){size_t f=fwrite(obuf,p3-obuf,1,stdout);p3=obuf;*p3=0;return f;}fastIO&operator>>(char&t){for(t=get();!isgraph(t);t=get()){;}return*this;}template<typename any>typename std::enable_if<std::is_same<any,char>::value,any>::type tpval(){char t;for(t=get();!isgraph(t);t=get()){;}return t;}fastIO&operator>>(char*t){char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())*t=c,t++;*t=0;return*this;}fastIO&operator>>(std::string&t){t.clear();char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())t+=c;return*this;}template<typename any>typename std::enable_if<std::is_same<any,std::string>::value,any>::type tpval(){std::string t;char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())t+=c;return t;}template<typename any>typename std::enable_if<(std::is_signed<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__int128_t>::value,fastIO>::type&operator>>(any&t){t=0;bool y=0;char c=get();for(;!isdigit(c);c=get())if(c==45)y=true;for(;isdigit(c);c=get())t=t*10+c-48;if(y==1)t=-t;return*this;}template<typename any>typename std::enable_if<(std::is_signed<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__int128_t>::value,any>::type tpval(){any t=0;bool y=0;char c=get();for(;!isdigit(c);c=get())if(c==45)y=true;for(;isdigit(c);c=get())t=t*10+c-48;if(y==1)t=-t;return t;}template<typename any>typename std::enable_if<(std::is_unsigned<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__uint128_t>::value,fastIO>::type&operator>>(any&t){t=0;char c=get();for(;!isdigit(c);c=get()){;}for(;isdigit(c);c=get())t=t*10+c-48;return*this;}template<typename any>typename std::enable_if<(std::is_unsigned<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__uint128_t>::value,any>::type tpval(){any t=0;char c=get();for(;!isdigit(c);c=get()){;}for(;isdigit(c);c=get())t=t*10+c-48;return t;}template<typename any1,typename any2>fastIO&operator>>(std::pair<any1,any2>&t){return*this>>t.first>>t.second;}template<typename any1,typename any2>std::pair<any1,any2>tpval(){return std::pair<any1,any2>(tpval<any1>(),tpval<any2>());}template<typename any>fastIO&read(any&t){return*this>>t;}fastIO&read(char*t){char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())*t=c,t++;*t=0;return*this;}template<typename any,typename...args>fastIO&read(any&t1,args&...t2){return(*this>>t1).read(t2...);}fastIO&operator<<(const char t){put(t);return*this;}fastIO&operator<<(const char*t){for(;*t;t++)put(*t);return*this;}fastIO&operator<<(const std::string&t){for(const char it:t)put(it);return*this;}template<typename any>typename std::enable_if<(std::is_signed<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__int128_t>::value,fastIO>::type&operator<<(any t){if(!t){put(48);return*this;}int len=0;if(t<0)t=-t,put(45);while(t)sta[len++]=char(t%10+48),t/=10;while(len--)put(sta[len]);return*this;}template<typename any>typename std::enable_if<(std::is_unsigned<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__uint128_t>::value,fastIO>::type&operator<<(any t){if(!t){put(48);return*this;}int len=0;while(t)sta[len++]=char(t%10+48),t/=10;while(len--)put(sta[len]);return*this;}template<typename any1,typename any2>fastIO&operator<<(const std::pair<any1,any2>&t){return*this<<t.first<<' '<<t.second;}template<typename any>fastIO&write(const any&t){return*this<<t;}template<typename any,typename...args>fastIO&write(const any&t1,const args&...t2){return(*this<<t1).write(t2...);}~fastIO(){fwrite(obuf,p3-obuf,1,stdout);}}fio;
class SegmentTree {
private:
    struct Node {
        int sum;
        int toAssign; // -1 means no assignment, 0 means assign 0, 1 means assign 1
        bool flip; // indicates whether to flip the segment
    };

    vector<Node> tree;
    int n;

    inline void push(int node, int start, int end) {
        if (tree[node].toAssign != -1) {
            // Apply assignment
            tree[node].sum = (end - start + 1) * tree[node].toAssign;
            if (start != end) {
                tree[(node << 1) + 1].toAssign = tree[node].toAssign;
                tree[(node << 1) + 2].toAssign = tree[node].toAssign;
                tree[(node << 1) + 1].flip = false;
                tree[(node << 1) + 2].flip = false;
            }
            tree[node].toAssign = -1;
        }

        if (tree[node].flip) {
            tree[node].sum = (end - start + 1) - tree[node].sum; // Flip the sum
            if (start != end) {
                if (tree[(node << 1) + 1].toAssign == -1) {
                    tree[(node << 1) + 1].flip = !tree[(node << 1) + 1].flip;
                } else {
                    tree[(node << 1) + 1].toAssign = 1 - tree[(node << 1) + 1].toAssign;
                }
                
                if (tree[(node << 1) + 2].toAssign == -1) {
                    tree[(node << 1) + 2].flip = !tree[(node << 1) + 2].flip;
                } else {
                    tree[(node << 1) + 2].toAssign = 1 - tree[(node << 1) + 2].toAssign;
                }
            }
            tree[node].flip = false;
        }
    }

    void build(const vector<int>& arr, int node, int start, int end) {
        if (start == end) {
            tree[node].sum = arr[start];
            tree[node].toAssign = -1;
            tree[node].flip = false;
            return;
        }
        int mid = (start + end) >> 1;
        build(arr, (node << 1) + 1, start, mid);
        build(arr, (node << 1) + 2, mid + 1, end);
        tree[node].sum = tree[(node << 1) + 1].sum + tree[(node << 1) + 2].sum;
        tree[node].toAssign = -1;
        tree[node].flip = false;
    }

    void updateAssign(int node, int start, int end, int l, int r, int value) {
        push(node, start, end);
        if (start > r || end < l) return;
        if (start >= l && end <= r) {
            tree[node].toAssign = value;
            push(node, start, end);
            return;
        }
        int mid = (start + end) >> 1;
        updateAssign((node << 1) + 1, start, mid, l, r, value);
        updateAssign((node << 1) + 2, mid + 1, end, l, r, value);
        tree[node].sum = tree[(node << 1) + 1].sum + tree[(node << 1) + 2].sum;
    }

    void updateFlip(int node, int start, int end, int l, int r) {
        push(node, start, end);
        if (start > r || end < l) return;
        if (start >= l && end <= r) {
            tree[node].flip = true;
            push(node, start, end);
            return;
        }
        int mid = (start + end) >> 1;
        updateFlip((node << 1) + 1, start, mid, l, r);
        updateFlip((node << 1) + 2, mid + 1, end, l, r);
        tree[node].sum = tree[(node << 1) + 1].sum + tree[(node << 1) + 2].sum;
    }

    int querySum(int node, int start, int end, int l, int r) {
        push(node, start, end);
        if (start > r || end < l) return 0;
        if (start >= l && end <= r) {
            return tree[node].sum;
        }
        int mid = (start + end) >> 1;
        int leftSum = querySum((node << 1) + 1, start, mid, l, r);
        int rightSum = querySum((node << 1) + 2, mid + 1, end, l, r);
        return leftSum + rightSum;
    }

public:
    SegmentTree(const vector<int>& arr) {
        n = arr.size();
        tree.resize(4 * n);
        build(arr, 0, 0, n - 1);
    }

    inline void updateAssign(int l, int r, int value) {
        updateAssign(0, 0, n - 1, l, r, value);
    }

    inline void updateFlip(int l, int r) {
        updateFlip(0, 0, n - 1, l, r);
    }

    inline int querySum(int l, int r) {
        return querySum(0, 0, n - 1, l, r);
    }
};
vector<int> g[20];
vector<SegmentTree> st;
int main() {
    int n, m;
    fio>> n >> m;
    for (register int i = 1; i <= n; i++) {
    	int tmp;
    	fio >> tmp;
    	for (register int j = 0; j <= 19; j++, tmp /= 2) {
    		g[j].push_back(tmp & 1);
		}
	}
	for (register int i = 0; i <= 19; i++) {
		SegmentTree tmp(g[i]);
		st.push_back(tmp);
	}
	while (m--) {
		int op, l, r;
		fio >> op >> l >> r;
		l--;
		r--;
		if (op == 1) {
			int tmp;
			fio >> tmp;
			for (register int j = 0; j <= 19; j++, tmp /= 2) {
				st[j].updateAssign(l, r, (tmp & 1));
			}
		} else if (op == 2) {
			int tmp;
			fio >> tmp;
			for (register int j = 0; j <= 19; j++, tmp /= 2) {
				if (tmp & 1) {
					st[j].updateFlip(l, r);
				}
			}
		} else if (op == 3) {
			long long ans = 0;
			for (register int j = 0, x = 1; j <= 19; j++, (x *= 2)) {
				ans = ans + (long long) st[j].querySum(l, r) * x;
			}
			fio << ans << "\n";
		}else if (op == 4) {
			long long ans = 0;
			for (register int j = 0, x = 1; j <= 19; j++, (x *= 2)) {
				int tmp = st[j].querySum(l, r);
				ans = ans + (long long) tmp * (r - l + 1 - tmp) * x;
			}
			fio << ans << "\n";
		}
	}
    return 0;
}
2024/10/2 10:19
加载中...