首页 > 其他分享 >loj6144「2017 山东三轮集训 Day6」C

loj6144「2017 山东三轮集训 Day6」C

时间:2023-03-20 15:57:08浏览次数:45  
标签:... ch args Day6 loj6144 trie int put 2017

loj6144「2017 山东三轮集训 Day6」C

注意到修改只有位运算,容易想到将位拆开考虑。首先可以发现对某一位或上 \(0\) 或者是对某一位与上 \(1\) 是没有意义的,相当于没有操作。

如果修改只有异或,那么只需要对每一位维护一个是否翻转的标记,然后建出可持久化 \(\text{trie}\),查询的时候只需要找到每一位值为 \(0\) 的子树(如果有标记就是 \(1\),否则就是 \(0\))检查子树大小是否超过 \(k\),如果超过 \(k\) 就向 \(0\) 子树走,否则向 \(1\) 子树走即可。

接下来考虑与 \(0\) 操作和或 \(1\) 操作,实际上将所有数的这一位都变成了相同的数。那么接下来只需要直接大力维护这一位是什么,二分的时候不考虑这一位即可。具体地,由于最多会有 \(\log w\) 次操作会使得至少一位变成相同的数,所以每次将某一位变成相同的数时直接暴力重构可持久化 \(\text{trie}\)。为了方便,可以将已经全都相同的位默认设为 \(0\),然后用另一个变量存储这些位的值,最后直接加上即可。

时间复杂度 \(\mathcal{O}(n \log^2 w)\)。

code
#include<bits/stdc++.h>
using namespace std;
namespace IO{
	template<typename T>inline bool read(T &x){
		x=0;
		char ch=getchar();
		bool flag=0,ret=0;
		while(ch<'0'||ch>'9') flag=flag||(ch=='-'),ch=getchar();
		while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(),ret=1;
		x=flag?-x:x;
        return ret;
	}
	template<typename T,typename ...Args>inline bool read(T& a,Args& ...args){
	    return read(a)&&read(args...);
	}
	template<typename T>void prt(T x){
		if(x>9) prt(x/10);
		putchar(x%10+'0');
	}
	template<typename T>inline void put(T x){
		if(x<0) putchar('-'),x=-x;
		prt(x);
	}
	template<typename T>inline void put(char ch,T x){
		if(x<0) putchar('-'),x=-x;
		prt(x);
		putchar(ch);
	}
	template<typename T,typename ...Args>inline void put(T a,Args ...args){
	    put(a);
		put(args...);
	}
	template<typename T,typename ...Args>inline void put(const char ch,T a,Args ...args){
	    put(ch,a);
		put(ch,args...);
	}
	inline void put(string s){
		for(int i=0,sz=s.length();i<sz;i++) putchar(s[i]);
	}
	inline void put(const char* s){
		for(int i=0,sz=strlen(s);i<sz;i++) putchar(s[i]);
	}
}
using namespace IO;
#define N 50005
#define M 3200005
#define K 31
#define int unsigned
int n,m,w[N],rt[N],trie[M][2],siz[M],idx;
int vis,rev,tag;
inline void insert(int x,int y,int val){
	if(!rt[x]) rt[x]=++idx;
	x=rt[x],y=rt[y];
	siz[x]=siz[y]+1;
	for(int i=K;~i;i--){
		int c=val>>i&1;
		if(vis>>i&1) c=0;
		trie[x][c^1]=trie[y][c^1];
		trie[x][c]=++idx;
		x=trie[x][c],y=trie[y][c];
		siz[x]=siz[y]+1;
	}
}
inline int query(int x,int y,int k){
	int res=0;
	for(int i=K;~i;i--){
		if(vis>>i&1){
			res|=tag&(1u<<i);
			x=trie[x][0],y=trie[y][0];
			continue;
		}
		int c=rev>>i&1;
		int lsiz=siz[trie[y][c]]-siz[trie[x][c]];
		if(lsiz<k) res|=1u<<i,c^=1,k-=lsiz;
		x=trie[x][c],y=trie[y][c]; 
	}
	return res;
}
inline void build(){
	memset(rt,0,sizeof(rt));
	memset(trie,0,sizeof(trie));
	memset(siz,0,sizeof(siz));
	idx=0;
	for(int i=1;i<=n;i++) insert(i,i-1,w[i]^=rev);
	rev=0;
}
char s[6];
signed main(){
	read(n,m);
	for(int i=1;i<=n;i++) read(w[i]);
	build();
	for(int i=1,x,y,k;i<=m;i++){
		scanf("%s",s),read(x);
		bool flag=0;
		if(s[1]=='o') rev^=x,tag^=x;
		else if(s[1]=='n'){
			tag&=x;
			for(int j=0;j<=K;j++)
				if(!(x>>j&1)){
					if(!(vis>>j&1)) vis|=1u<<j,flag=1;
					rev-=rev&(1u<<j);
				}
		}else if(s[1]=='r'){
			tag|=x;
			for(int j=0;j<=K;j++)
				if(x>>j&1){
					if(!(vis>>j&1)) vis|=1u<<j,flag=1;
					rev|=1u<<j;
				}
		}else read(y,k),put('\n',query(rt[x-1],rt[y],k));
		if(flag) build();
	}
	return 0;
}

标签:...,ch,args,Day6,loj6144,trie,int,put,2017
From: https://www.cnblogs.com/fzj2007/p/17236586.html

相关文章

  • day60
    1、leetcode84柱状图中的最大矩形思路【宫水三叶题解】最终矩形的高度必然取自某个heights[i],因此我们可以枚举最终矩形的高度来做。问题转换为当使用某个heights[i......
  • PA 2017 Banany
    $$是夜萧索漏星光,一秋叶打漫天霜。钟响,卷地西风扫鸿芒。$$$$求索那堪路漫长,重心剖树早相忘。清唱,时空阻限又何妨?$$PA-2017Banany考虑点分树。先把点分树建出来再考虑更......
  • 「JOISC2017」门票安排
    题目点这里看题目。分析不妨先认为\(C_i=1\)。首先破环为链,则原问题等价于:你有一个长度为\(n\)的序列\(a\)和\(m\)个二元组\((l_i,r_i)\)。一开始时,\(a_i=0\)......
  • 【漏洞复现】Apache HTTPD 换行解析漏洞 (CVE-2017-15715)
    ApacheHTTPD换行解析漏洞(CVE-2017-15715)0x01漏洞描述ApacheHTTPD是一款HTTP服务器,它可以通过mod_PHP来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞,在解......
  • 学习日记-Day6
    日期2023-3-11任务列表计网复习TCP、IP、HTTP协议【100%】巩固数据库和软工知识【100%】综合面两个问题【100%】离散数学:订正第六章习题【100%】leetcode:多种方法......
  • csp201703-2
    这道题暴力能过,最离谱的是,我提交了,通过了100分,返回来看一眼代码发现我的数组只开了a[10].....这数据给的太随意了吧#include<bits/stdc++.h>usingnamespacestd;inta......
  • CCF 2017-12
    一:试题编号:2017-12-1试题名称:最小差值时间限制:1.0s内存限制:256.0MB问题描述:问题描述 给定n个数,请找出其中相差(差的绝对值)最小的两个数,输出它们的差值的绝对值。输入格式......
  • P4434 [COCI2017-2018#2] ​​Usmjeri
    知识点:lca,种类并查集新生赛原题。什么嘛,我还是长了一点手的嘛简述给定一棵\(n\)个节点的树,初始时每条边方向不确定,同时给定\(m\)组约束,第\(i\)组约束为\((a_i,......
  • 《渗透测试》抓包技术&HTTPS协议&APP&小程序&PC应用&WEB&转发联动 2023 day6&7
      准备工作:1、浏览器安装证书:解决本地抓HTTPS1.1打开burpsuite的Proxy模块   1.2点击下方的import/exportCAcertificate选择输出的第一个按钮 1.3......
  • csp201709-2
    题目:计算机软件能力认证考试系统直接对时间进行枚举,本以为会超时,没想到过了,过了就过了、、 #include<bits/stdc++.h>usingnamespacestd;set<int>keep[10105];se......