[FJOI2015]火星商店问题

description

题面

solution

跟着各位dalao写了一下线段树分治的题

我们把修改和询问按照时间建立线段树分治,
对于每一个修改标记永久化,对于每一个区间进行区间覆盖

主要的想法就是对每一个线段树节点开一个\(vector\)记录所有的修改和询问
在线段树上的一条链上插入修改,使用区间覆盖的方法在线段树上插入询问
对整棵线段树进行\(dfs\),每次取出节点上的\(vector\)并对其进行处理
大概就是这样

void segdiv(int i,int l,int r){//线段树分治???
	work(f[i],g[i]);if(l==r)return;segdiv(ls,l,mid);segdiv(rs,mid+1,r);
}

il void insertmodify(int i,int l,int r,int x,int y,modify mdf){
    //这里是插入修改
	f[i].push_back(mdf);
	if(l==r)return;
	if(x<=mid)insertmodify(ls,l,mid,x,y,mdf);
	else insertmodify(rs,mid+1,r,x,y,mdf);
}
il void insertquery(int i,int l,int r,int x,int y,ask q){
    //这里是插入询问
	if(y<x)return;
	if(x<=l&&r<=y){g[i].push_back(q);return;}
	if(x<=mid)insertquery(ls,l,mid,x,y,q);
	if(mid<y)insertquery(rs,mid+1,r,x,y,q);
}

code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=1e5+10;
const int T=5e6+10;
const dd pi=acos(-1);
const int inf=2147483647;
const ll INF=1e18+1;
il ll read(){
	RG ll data=0,w=1;RG char ch=getchar();
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
	return data*w;
}
il void file(){
	srand(time(NULL)+rand());
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
}

struct modify{int a,b,day;}M[N];
bool cmp(modify x,modify y){return x.a<y.a;}
struct ask{int id,a,b,c,d,e;}Q[N];
int n,m,day,mt,qt,ans[N],pw[21],tot,num[N],sz;
vector<modify>f[N<<5];
vector<ask>g[N<<5];
int rt[N],s[N<<5][2],sum[N<<5];
il void insert(int cur,int lst,int val){
	sum[cur]=sum[lst]+1;bool d;
	for(RG int i=17;~i;i--){
		d=val&pw[i];
		s[cur][d]=++tot;s[cur][!d]=s[lst][!d];
		sum[s[cur][d]]=sum[s[lst][d]]+1;
		cur=s[cur][d];lst=s[lst][d];
	}
}
il int query(int l,int r,int x){
	if(l>r)return 0;
	l=rt[l-1];r=rt[r];bool d;int ret=0;
	for(RG int i=17;~i;i--){
		d=x&pw[i];
		if(sum[s[r][!d]]-sum[s[l][!d]]>0){
			ret|=pw[i];r=s[r][!d];l=s[l][!d];
		}
		else{r=s[r][d];l=s[l][d];}
	}
	return ret;
}
void work(vector<modify>F,vector<ask>G){
	RG int ft=F.size(),gt=G.size();
	tot=sz=0;
	for(RG int i=0;i<ft;i++){
		num[++sz]=F[i].a;
		insert(rt[i+1]=++tot,rt[i],F[i].b);
	}
	for(RG int i=0,l,r;i<gt;i++){
		l=lower_bound(num+1,num+sz+1,G[i].a)-num;
		r=upper_bound(num+1,num+sz+1,G[i].b)-num-1;
		ans[G[i].id]=max(ans[G[i].id],query(l,r,G[i].e));
	}
}

#define ls (i<<1)
#define rs (i<<1|1)
#define mid ((l+r)>>1)
il void insertmodify(int i,int l,int r,int x,int y,modify mdf){
	f[i].push_back(mdf);
	if(l==r)return;
	if(x<=mid)insertmodify(ls,l,mid,x,y,mdf);
	else insertmodify(rs,mid+1,r,x,y,mdf);
}
il void insertquery(int i,int l,int r,int x,int y,ask q){
	if(y<x)return;
	if(x<=l&&r<=y){g[i].push_back(q);return;}
	if(x<=mid)insertquery(ls,l,mid,x,y,q);
	if(mid<y)insertquery(rs,mid+1,r,x,y,q);
}
void segdiv(int i,int l,int r){
	work(f[i],g[i]);if(l==r)return;segdiv(ls,l,mid);segdiv(rs,mid+1,r);
}

int main()
{
	n=read();m=read();pw[0]=1;for(RG int i=1;i<=20;i++)pw[i]=pw[i-1]<<1;
	for(RG int i=1;i<=n;i++)insert(rt[i]=++tot,rt[i-1],read());
	for(RG int i=1,o,a,b,c,d;i<=m;i++){
		o=read();
		if(!o){day++;a=read();b=read();M[++mt]=(modify){a,b,day};}
		else{
			a=read();b=read();d=read();c=read();
			Q[++qt]=(ask){qt,a,b,max(day-c,0)+1,day,d};
		}
	}
	for(RG int i=1;i<=qt;i++)
		ans[i]=max(ans[i],query(Q[i].a,Q[i].b,Q[i].e));
	sort(M+1,M+mt+1,cmp);	
	for(RG int i=1;i<=mt;i++)insertmodify(1,1,day,M[i].day,day,M[i]);
	for(RG int i=1;i<=qt;i++)
		if(Q[i].d)insertquery(1,1,day,max(Q[i].c,1),Q[i].d,Q[i]);
	segdiv(1,1,day);	
	for(RG int i=1;i<=qt;i++)printf("%d\n",ans[i]);return 0;
}

posted @ 2018-07-27 20:37  cjfdf  阅读(147)  评论(0编辑  收藏  举报