BZOJ4137 & 洛谷4585:[FJOI2015]火星商店问题

https://www.lydsy.com/JudgeOnline/problem.php?id=4137

https://www.luogu.org/problemnew/show/P4585

火星上的一条商业街里按照商店的编号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。

参考:https://blog.csdn.net/lvzelong2014/article/details/78688727

继续练习线段树分治,虽然还是离不开题解但是已经知道拿什么分治了

以及越来越深感线段树分治并不是线段树这一个事实了,开个专栏吧

显然d的存在使得一些商品被“撤销”了,但是每个人的d都是不同的,我们就没法把商品放到线段树上。

于是反其道而行之,把人扔到线段树上,把商品放到线段树上跑。

然后每次询问异或最大值就是可持久化trie了。

PS:时刻注意这里面有两个量:商品所在的商店,以及商品上货时间。不要搞混了。

我们预先按照商店排序,然后根据当前的时间区间再重新分配即可(有点像整体二分)。

#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int B=17;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct data{
    int l,r,x,L,R;
}p[N];
struct good{
    int s,v,t;
}q[N],tmpl[N],tmpr[N];
struct node{
    int son[2],sum;
}tr[N*40];
int n,m,pcnt,qcnt,ans[N],rt[N],num[N],pool;
vector<int>seg[N*4];
inline bool cmp(good a,good b){
    return a.s<b.s;
}
void insert(int y,int &x,int k,int now){
    tr[x=++pool]=tr[y];
    tr[x].sum++;
    if(now<0)return;
    bool p=k&(1<<now);
    insert(tr[y].son[p],tr[x].son[p],k,now-1);
    return;
}
int query(int nl,int nr,int k,int now){
    if(now<0)return 0;
    bool p=k&(1<<now);
    int delta=tr[tr[nr].son[p^1]].sum-tr[tr[nl].son[p^1]].sum;
    if(delta>0)return (1<<now)+query(tr[nl].son[p^1],tr[nr].son[p^1],k,now-1);
    else return query(tr[nl].son[p],tr[nr].son[p],k,now-1);
}
void add(int a,int l,int r,int l1,int r1,int x){
    if(r<l1||r1<l)return;
    if(l1<=l&&r<=r1){
        seg[a].push_back(x);return;
    }
    int mid=(l+r)>>1;
    add(a<<1,l,mid,l1,r1,x);add(a<<1|1,mid+1,r,l1,r1,x);
}
int find(int l,int r,int k){
    l--;
    while(l<r){
        int mid=(l+r+1)>>1;
        if(num[mid]<=k)l=mid;
        else r=mid-1;
    }
    return l;
}
void work(int a,int l,int r){
    pool=0;int cnt=0;
    for(int i=l;i<=r;i++){
        num[++cnt]=q[i].s;
        insert(rt[cnt-1],rt[cnt],q[i].v,B);
    }
    for(int i=0;i<seg[a].size();i++){
        int id=seg[a][i];
        int L=find(1,cnt,p[id].l-1),R=find(1,cnt,p[id].r);
        ans[id]=max(ans[id],query(rt[L],rt[R],p[id].x,B));
    }
}
void divide(int a,int l,int r,int l1,int r1){
    int mid=(l+r)>>1,len1=0,len2=0;
    work(a,l1,r1);
    for(int i=l1;i<=r1;i++){
        if(q[i].t<=mid)tmpl[len1++]=q[i];
        else tmpr[len2++]=q[i];
    }
    for(int i=0;i<len1;i++)q[i+l1]=tmpl[i];
    for(int i=0;i<len2;i++)q[i+l1+len1]=tmpr[i];
    if(l==r)return;
    divide(a<<1,l,mid,l1,l1+len1-1);
    divide(a<<1|1,mid+1,r,l1+len1,r1);
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)insert(rt[i-1],rt[i],read(),B);
    for(int i=1;i<=m;i++){
        int op=read();
        if(!op){
            q[++qcnt].s=read();q[qcnt].v=read();
            q[qcnt].t=qcnt;
        }else{
            p[++pcnt].l=read();p[pcnt].r=read();
            p[pcnt].x=read();int d=read();
            p[pcnt].L=max(qcnt-d+1,1);p[pcnt].R=qcnt;
            ans[pcnt]=query(rt[p[pcnt].l-1],rt[p[pcnt].r],p[pcnt].x,B);
        }
    }
    for(int i=1;i<=pcnt;i++)add(1,1,qcnt,p[i].L,p[i].R,i);
    sort(q+1,q+qcnt+1,cmp);
    divide(1,1,qcnt,1,qcnt);
    for(int i=1;i<=pcnt;i++)printf("%d\n",ans[i]);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

猜你喜欢

转载自www.cnblogs.com/luyouqi233/p/9091014.html