zoukankan      html  css  js  c++  java
  • 题解 CF587E 【Duff as a Queen】

    题目链接

    本题类似于[Ynoi2013]无力回天NOI2017

    Solution CF587E Duff as a Queen

    题目大意:维护一个序列,支持区间异或一个值,询问一段区间内有多少种任意子集的异或值

    线段树,线性基


    分析:

    想这个题的时候有一个假了的地方:线性基是离线数据结构,没办法快速实现区间修改。把线性基里面所有数拖出来异或一遍再插回去,这个做法是假的

    类似于用 (gcd(x,y)=gcd(y,x-y)) 这个性质做差分,变区间修改为单点修改从而实现区间加区间 (gcd),我们尝试对原序列进行等价转化,使得修改操作可以快速进行

    假设原序列为 (a),那么我们令 (b_i=a_i;xor;a_{i+1}),对于原序列 (a_iquad i in[l,r]),我们可以用 (b_i quad iin(l,r]) 以及 (a_l) 来表示

    这样我们只需要维护单点修改,区间查询线性基的并。以及维护区间异或,单点查询原序列

    可以用树状数组和线段树来维护

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    using namespace std;
    const int maxn = 2e5 + 100;
    inline int read(){
    	int x = 0;char c = getchar();
    	while(!isdigit(c))c = getchar();
    	while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    	return x;
    }
    struct Base{
        static const int mx = 31;
        int p[mx + 1];
        inline void ins(int x){
            for(int i = mx;i >= 0;i--){
                if(!((x >> i) & 1))continue;
                if(!p[i]){
                    p[i] = x;
                    break;
                }
                x ^= p[i];
            }
        }
        inline void ins(const Base &rhs){
            for(int i = 0;i <= mx;i++)
                ins(rhs.p[i]);
        }
        inline int query()const{
            int res = 0;
            for(int i = 0;i <= mx;i++)
                if(p[i])res++;
            return (1ll << res);
        }
        inline void clear(){memset(p,0,sizeof(p));}
    };
    int org[maxn],val[maxn],n,q;
    namespace st{
    	#define ls (rt << 1)
    	#define rs (rt << 1 | 1)
    	struct node{
    		int real;
    		Base val;
    	}tr[maxn << 2];
    	inline void pushup(int rt){
    		tr[rt].val = tr[ls].val;
    		tr[rt].val.ins(tr[rs].val);
    	}
    	inline void build(int l = 0,int r = n,int rt = 1){
    		if(l == r){
    			tr[rt].real = val[l];
    			tr[rt].val.ins(val[l]);
    			return;
    		}
    		int mid = (l + r) >> 1;
    		build(l,mid,ls);
    		build(mid + 1,r,rs);
    		pushup(rt);
    	}
    	Base res;
    	inline void query(int a,int b,int l = 0,int r = n,int rt = 1){
    		if(a <= l && b >= r){
    			res.ins(tr[rt].val);
    			return;
    		}
    		int mid = (l + r) >> 1;
    		if(a <= mid)query(a,b,l,mid,ls);
    		if(b >= mid + 1)query(a,b,mid + 1,r,rs);
    	}
    	inline void modify(int pos,int v,int l = 0,int r = n,int rt = 1){
    		if(l == r){
    			tr[rt].real ^= v;
    			tr[rt].val.clear();
    			tr[rt].val.ins(tr[rt].real);
    			return;
    		}
    		int mid = (l + r) >> 1;
    		if(pos <= mid)modify(pos,v,l,mid,ls);
    		else modify(pos,v,mid + 1,r,rs);
    		pushup(rt);
    	}
    }
    namespace bit{
    	int f[maxn];
    	inline int lowbit(int x){return x & (-x);}
    	inline int query(int pos){
    		int res = 0;
    		while(pos){
    			res ^= f[pos];
    			pos -= lowbit(pos);
    		}
    		return res;
    	}
    	inline void modify(int pos,int v){
    		if(!pos)return;
    		while(pos < maxn){
    			f[pos] ^= v;
    			pos += lowbit(pos);
    		}
    	}
    	inline void modify(int l,int r,int v){
    		modify(l,v);
    		modify(r + 1,v);
    	}
    }
    int main(){
    	n = read(),q = read();
    	for(int i = 1;i <= n;i++)org[i] = read();
    	for(int i = 1;i <= n;i++)bit::modify(i,i,org[i]);
    	for(int i = 1;i <= n;i++)val[i] = org[i] ^ org[i + 1];
    	st::build();
    	while(q--){
    		const int opt = read(),x = read(),y = read();
    		if(opt == 1){
    			const int k = read();
    			st::modify(x - 1,k);
    			st::modify(y,k);
    			bit::modify(x,y,k);
    		}else{
    			st::res.clear();
    			if(x != y)st::query(x,y - 1);
    			st::res.ins(bit::query(x));
    			printf("%d
    ",st::res.query());
    		}
    	}
    }
    
  • 相关阅读:
    团队-团队编程项目作业名称-最终程序
    《团队-中国象棋-项目总结》
    课后作业-阅读任务-阅读提问-4
    《20171130-构建之法:现代软件工程-阅读笔记4》
    《软件工程课程总结》
    《20171117-构建之法:现代软件工程-阅读笔记-3》
    -课后作业-阅读任务-阅读提问-3
    《团队-中国象棋-团队一阶段互评》
    《团队-中国象棋-开发文档》
    《结对-贪吃蛇-结对项目总结》
  • 原文地址:https://www.cnblogs.com/colazcy/p/13961449.html
Copyright © 2011-2022 走看看