zoukankan      html  css  js  c++  java
  • [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
    ",ans[i]);return 0;
    }
    
    
  • 相关阅读:
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    综合练习:词频统计
    【Art】虹吸原理(5月份订正版)
    【失踪人口】准初三的JZSC
    【Mood】出大问题(最近很喜欢说这句话)
    【Matrix】矩阵加法&乘法
    【C++】stdio.h和cstdio
    【Theorem】中国剩余定理
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9379550.html
Copyright © 2011-2022 走看看