[羅区P4585] [FJOI2015]火星ショップ問題

説明

数に応じて、火星上の商店街店\(1 \)、\ (2 \)、...、 \ (N \) 優先度の順に\(N \)を格納します。店舗で販売商品のアレイは、各商品は、非負整数使用している\(ヴァル\)価格にします。毎日いくつかの新しい商品を各店舗に入る可能性がある、価格は従来品と同じであってもよいです。

この商店街の買い物の時には火星には、通常、道路のセクションに全店舗この商店街を訪問し、区間における店舗数を言う\([L、R]は\ ) 店で、選択し、あなたが一番好きなものを選びます商品。標準品の各火星異なる好み。一般的に、各火星は独自の好みのパスワードがある\(X- \を)で販売それぞれについて\(ヴァル\)パスワードのような、商品\(X \)この商品との優先度火星\(ヴァル\) XOR \(x \)値に比例します。言い換えれば、\(ヴァル\) \(XOR \) \(X- \)より大きな値は、より多くの彼は、製品が好きでした。各火星のショッピングカードは、すべての最近の店舗で購入することができます\(dは\) 当日を含む)の日が商品を購入します。また、各店舗は除外日なしの特別商品購入を持って、それぞれの火星は、任意の時点で特定の商品を選択することができます。各店舗での各製品は、問題が存在しないのうち物資の供給を保証することができます。

火星のこのショッピング・イベント好きな商品に各ショッピング、その出力について計算年代順に与えられたイベントについては、\(ヴァル\) \(XOR \) \(X- \)最大。イベントの年代順にここでいう、次の手段である\(2 \)イベントの種類:

イベント\(0 \) 3つの整数で、\(0 \) \(S \) \(V \) その数はある\(S \)値札の同じ日に新しい一種の店舗\(vは\)品。

イベント\(1 \)\(5 \)の整数\(1 \)は、$ Lの$、\(R \) \(X- \) \(dは\)が、中に火星の日を表し第\(Lの\は)する(R \)\買いに店を(dは\)\コモディティ日、火星好みのパスワード\(X- \)

入力

最初の行は、正の整数2与えられ\(N- \) \(m個\)を、総数とイベントショップの総数を表します。

2行目有する\(N- \)整数、\(Iは\)番目の整数ストア\(Iは\)商品の特別価格。

\(Mの\)ラインは、各ラインが表す\(1 \)イベント。最初のイベントで毎日のイベント\(0 \) イベント\(1 \)が順次配置されています。

出力

算出された各イベント\(1 \)\(ヴァル\) \(XOR \) \(X \)最大出力を順次。

サンプル入力

4 6
1 2 3 4
1 1 4 1 0
0 1 4
0 1 3
1 1 1 1 0
1 1 1 1 1
1 1 2 1 2

サンプル出力

5
0
2
5

ヒント

\(N、Mの\の当量100000 \)

データの価格を超えない\(100000 \)


考え

まずTucaoタイトルの顔!私はそれがより嫌に比べてそれがより明確に入れて見ていません。
以下のように定義される「毎日」:イベントが0の発生は、最初のイベントの前にイベントで、新しい一日の始まりである0日0とみなすことができる起こります。

2つの方法でXORと最大要件、1は直鎖状の基Aが永続的である\(トライ\) この質問の持続性をすることができる(トライ\)を\容易になります。
時代を超越した特殊な商品については、直接店舗番号への持続的な構築するためにバージョン番号です\(トライ\) クエリ、答えを更新します。
一見他のアクションは非常に複雑なようです。
店舗番号としてなら\(X \)として軸と時間\(Yの\)軸、実際には、問い合わせ及び2次元マトリクス+の単一のポイントを追加することである\(X \)最大とXORです。

これは、木のカバーの木(ツリーライン+永続必要があります\(トライ\))Aを。
番号が添字ビルドツリーライン、各ノードが持続性のバージョン番号に間に合うように構築される線分のツリーを保存するには、\(トライ\) (〜ラインにあなたを回す)
が、このスペースは生きていない場合。

だから、セグメントツリーパーティション。
各クエリに各分割\は、(O(LOGN)\)セグメントツリーノード上に配置された部品
の各ノードは、ツリーの行を横断するためには、オンサイトの成果、クエリーは、解答を更新します。

総複雑\(O(nlog ^ 2n個) \)


コード

これは良い書き込みコード......ではない非常にいい曲ではありません。
試料上の転送後にのみ弱い慰めデータ、\(図1A \) A。
(\ (PS \)選手の配列へのポインタ......それの選手になっているようです)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>

using namespace std;

int read(){
    int x=0;
    char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    return x;
}

const int N = 100005;

struct commo{ int x,d; };
struct query{ int x,l,r,id; };
int n,m;
int spi[N],ans[N];

int rt[N],cnt2,son[N*20][2],sum[N*20];
void clear(int x){
    for(int i=0;i<cnt2;i++) son[i][0]=son[i][1]=0,sum[i]=0;
    cnt2=0; 
    for(int i=0;i<=x;i++) rt[i]=0;
    if(x==-1) memset(rt,0,sizeof(rt));
}
void insert(int x,int pre,int dep,int c){
    if(dep==-1) { sum[x]=sum[pre]+1; return; }
    int f=((c>>dep)&1);
    son[x][f^1]=son[pre][f^1];
    insert(son[x][f]=++cnt2,son[pre][f],dep-1,c);
    sum[x]=sum[pre]+1;
}
int ask(int x,int pre,int dep,int c){
    if(dep==-1) return 0;
    int f=((c>>dep)&1); 
    if(sum[son[x][f^1]]>sum[son[pre][f^1]]) return (1<<dep)+ask(son[x][f^1],son[pre][f^1],dep-1,c);
    return ask(son[x][f],son[pre][f],dep-1,c);
}

int root,cnt;
int ch[N*2][2];
vector<commo> v[N*2];
vector<query> q[N*2];
void build(int x,int l,int r){
    if(l==r) return;
    int mid=(l+r)>>1;
    build(ch[x][0]=++cnt,l,mid);
    build(ch[x][1]=++cnt,mid+1,r);
}
void modify(int x,int l,int r,int c,commo d){
    v[x].push_back(d);
    if(l==r) return;
    int mid=(l+r)>>1;
    if(c<=mid) modify(ch[x][0],l,mid,c,d);
    else modify(ch[x][1],mid+1,r,c,d);
}
void add(int x,int l,int r,int L,int R,query d){
    if(l>=L && r<=R) { q[x].push_back(d); return; }
    int mid=(l+r)>>1;
    if(R>mid) add(ch[x][1],mid+1,r,L,R,d);
    if(L<=mid) add(ch[x][0],l,mid,L,R,d);
}

int b[N],tot;
void work(int x,int l,int r){
    if(q[x].size()){
        tot=0;
        for(int i=0;i<v[x].size();i++) b[++tot]=v[x][i].d;
        sort(b+1,b+1+tot);
        tot=unique(b+1,b+1+tot)-b-1; 
        for(int i=0;i<v[x].size();i++){
            int id=lower_bound(b+1,b+1+tot,v[x][i].d)-b,pre;
            pre=(rt[id] ? rt[id] : rt[id-1]);
            insert(rt[id]=++cnt2,pre,17,v[x][i].x);
        }
        
        for(int i=0;i<q[x].size();i++){
            if(q[x][i].l>q[x][i].r) continue;
            int ll=lower_bound(b+1,b+1+tot,q[x][i].l)-b-1,rr=upper_bound(b+1,b+1+tot,q[x][i].r)-b-1;
            if(ll<rr) {
                ans[q[x][i].id]=max(ans[q[x][i].id],ask(rt[rr],rt[ll],17,q[x][i].x));
            }
        }
        
        clear(tot);
    }
    
    if(l==r) return;
    int mid=(l+r)>>1;
    work(ch[x][0],l,mid); work(ch[x][1],mid+1,r);
}

int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++) spi[i]=read();
    
    clear(-1);
    for(int i=1;i<=n;i++)
        insert(rt[i]=++cnt2,rt[i-1],17,spi[i]);
    
    int opt,day=1,ques=0,l,r,d,x;
    build(root=++cnt,1,n);
    for(int i=0;i<m;i++){
        opt=read();
        if(opt==0) {
            l=read(); x=read();
            modify(root,1,n,l,(commo){x,++day});
        }
        else{
            l=read(); r=read(); x=read(); d=read();
            add(root,1,n,l,r,(query){x,max(day-d+1,1),day,ques++});
            ans[ques-1]=ask(rt[r],rt[l-1],17,x);
        }
    }
    clear(n);
    
    work(root,1,n);
    for(int i=0;i<ques;i++) printf("%d\n",ans[i]);
    
    return 0;
} 

おすすめ

転載: www.cnblogs.com/lindalee/p/11371832.html