zoukankan      html  css  js  c++  java
  • [FJOI2015]火星商店问题(分治+可持久化)

    题目描述

    火星上的一条商业街里按照商店的编号1,2 ,…,n ,依次排列着n个商店。商店里出售的琳琅满目的商品中,每种商品都用一个非负整数val来标价。每个商店每天都有可能进一些新商品,其标价可能与已有商品相同。

    火星人在这条商业街购物时,通常会逛这条商业街某一段路上的所有商店,譬如说商店编号在区间[L,R]中的商店,从中挑选1件自己最喜欢的商品。每个火星人对商品的喜好标准各不相同。通常每个火星人都有一个自己的喜好密码x。对每种标价为val的商品,喜好密码为x的火星人对这种商品的喜好程度与val异或x的值成正比。也就是说,val xor x的值越大,他就越喜欢该商品。每个火星人的购物卡在所有商店中只能购买最近d天内(含当天)进货的商品。另外,每个商店都有一种特殊商品不受进货日期限制,每位火星人在任何时刻都可以选择该特殊商品。每个商店中每种商品都能保证供应,不存在商品缺货的问题。

    对于给定的按时间顺序排列的事件,计算每个购物的火星人的在本次购物活动中最喜欢的商品,即输出val xor x的最大值。这里所说的按时间顺序排列的事件是指以下2种事件:

    事件0,用三个整数0,s,v,表示编号为s的商店在当日新进一种标价为v 的商品。

    事件1,用5个整数1,L,R,x,d,表示一位火星人当日在编号为L到R的商店购买d天内的商品,该火星人的喜好密码为x。

    题解

    考虑如果没有时间限制,我们可以选取的区间为连续一段,那样就是简单的按位贪心,可以用可持久化trie维护。

    现在有了时间限制,我们考虑分治,每个询问所覆盖的都是连续一段区间,而且修改之间是独立的,我们可以把每个询问拆成log个挂在按照时间建立的线段树上,然后按时间在线段树上分治。

    我们可以每次都重构trie,复杂度是对的。

    代码

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #define N 210002
    using namespace std;
    vector<int>vec[N<<2];
    int len=18,tot,inv[20],T[N],ans[N],n,m,tim,top;
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x; 
    }
    struct TRIE{
        int ch[N*22][2],size[N*22];
        inline void ins(int &now,int pre,int x,int deep){
            now=++tot;ch[now][0]=ch[pre][0];ch[now][1]=ch[pre][1];size[now]=size[pre]+1;
            if(deep<0)return;
            if(x&(1<<deep))ins(ch[now][1],ch[pre][1],x,deep-1);
            else ins(ch[now][0],ch[pre][0],x,deep-1);
        }
        inline int query(int now,int pre,int x,int deep){
            if(deep<0)return 0;
            int o=(x&(1<<deep))!=0,num=size[ch[now][!o]]-size[ch[pre][!o]];
            if(num)return inv[deep]+query(ch[now][!o],ch[pre][!o],x,deep-1);
            else return query(ch[now][o],ch[pre][o],x,deep-1);
        }
    }tr;
    struct node{
        int pos,val,tim;
        bool operator <(const node &b)const{return pos<b.pos;}
    }co[N],q1[N],q2[N];
    struct nod{int l,r,x,st,en;}q[N];
    void calc(int cnt,int l,int r){
        int top=0;tot=0;
        for(int i=l;i<=r;++i){
            ++top;
            tr.ins(T[top],T[top-1],co[i].val,len);
        }
        for(int i=0;i<vec[cnt].size();++i){
            int id=vec[cnt][i];node x;
            x.pos=q[id].l-1;
            int L=upper_bound(co+l,co+r+1,x)-co-l;//!!!!
            x.pos=q[id].r;
            int R=upper_bound(co+l,co+r+1,x)-co-l;
            ans[id]=max(ans[id],tr.query(T[R],T[L],q[id].x,len));
        }
    }
    void upd(int cnt,int l,int r,int L,int R,int x){
        if(L>R)return;
        if(l>=L&&r<=R){vec[cnt].push_back(x);return;}
        int mid=(l+r)>>1;
        if(mid>=L)upd(cnt<<1,l,mid,L,R,x);
        if(mid<R)upd(cnt<<1|1,mid+1,r,L,R,x);
    }
    void solve(int cnt,int l,int r,int L,int R){
        if(l>r||L>R)return;
        int mid=(l+r)>>1;
        calc(cnt,L,R);
        int o=0,p=0;
        for(int i=L;i<=R;++i){
            if(co[i].tim<=mid)q1[++o]=co[i];
            else q2[++p]=co[i];
        }
        for(int i=1;i<=o;++i)co[L+i-1]=q1[i];
        for(int i=1;i<=p;++i)co[L+o+i-1]=q2[i];
        if(l!=r)solve(cnt<<1,l,mid,L,L+o-1);
        solve(cnt<<1|1,mid+1,r,L+o,R);
    }
    int main(){
        n=rd();m=rd();int l,r,x,d,v,opt;
        for(int i=1;i<=n;++i)x=rd(),tr.ins(T[i],T[i-1],x,len);
        inv[0]=1;
        for(int i=1;i<=len;++i)inv[i]=inv[i-1]<<1;
        for(int i=1;i<=m;++i){
            opt=rd();
            if(opt){
                l=rd();r=rd();x=rd();d=rd();
                q[++top]=nod{l,r,x,max(1,tim-d+1),tim};
                ans[top]=tr.query(T[r],T[l-1],x,len);
            } 
            else{
                tim++;x=rd();v=rd();co[tim]=node{x,v,tim};
            }
        }
        sort(co+1,co+tim+1);
        for(int i=1;i<=top;++i)upd(1,1,tim,q[i].st,q[i].en,i);
        solve(1,1,tim,1,tim);
        for(int i=1;i<=top;++i)printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    个人笔记 1.3.net 3.5新特性
    个人笔记 1.2.net 2.0新特性
    面试了,web标准能简单说下吗?w3c,,错了
    SEO网络营销热门关键词排名较好的反向链接
    eWebEditor在ie8下上传失效
    个人笔记 1.4.net 3.0新特性
    个人笔记 1.5.http状态值
    MOSS项目开发(5) 会议还是会议
    MOSS项目开发 周记(第二周)
    MOSS项目开发 周记(第五周)
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10146883.html
Copyright © 2011-2022 走看看