Luogu4585 FJOI2015 Mars segment tree store issues divide and conquer, may persist Trie

Portal


Compare apparently think this question can be persistent Trie, we can direct the special commodity for persistence Trie statistical answer.

For added goods and query operations, we maintain a tree line, tree line maintenance Meike all Trie index number within this range for each node in the Trie while maintaining maximum modification time, so once asked can correspond to a segment tree log Trie then ask. Time and space complexity \ (O (nlog ^ 2n) \) .

Space complexity a bit high considering optimization. Noticed by force, we can ask all operations and operating on the basis of the above offline hung on the tree line corresponding node, and then for each node of the tree line with Trie do it again. Such space complexity is \ (O (nlogn) \) is.

We also can mark off time for the tree line, tree line that is divide and conquer, the basic idea is the same.

#include<bits/stdc++.h>
using namespace std;

int read(){
    int a = 0; char c = getchar();
    while(!isdigit(c)) c = getchar();
    while(isdigit(c)){a = a * 10 + c - 48; c = getchar();}
    return a;
}

const int _ = 1e5 + 7;

namespace Trie{
    const int __ = _ * 40;
    int ch[__][2] , lst[__] , cnt;

    int create(int x){int t = ++cnt; ch[t][0] = ch[x][0]; ch[t][1] = ch[x][1]; lst[t] = lst[x]; return t;}
    
    void ins(int &rt , int t , int x){
        rt = create(rt); int cur = rt;
        for(int i = 17 ; i >= 0 ; --i){
            bool flg = x >> i & 1; lst[cur = ch[cur][flg] = create(ch[cur][flg])] = t;
        }
    }

    int qry(int rt , int x , int t){
        int sum = 0;
        for(int i = 17 ; i >= 0 ; --i){
            bool flg = !(x >> i & 1);
            if(lst[ch[rt][flg]] >= t){sum |= 1 << i; rt = ch[rt][flg];}
            else rt = ch[rt][!flg];
        }
        return sum;
    }
}

struct query{int L , R , val , id;};
struct modify{int plc , num;};
int N , M , Q , cnt , ans[_] , rt[_];

namespace segt{
    vector < query > qry[_ << 2]; vector < modify > mdy[_ << 2];
    
#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)

    void ins(int x , int l , int r , int L , int R , query q){
        if(l >= L && r <= R) return qry[x].push_back(q);
        if(mid >= L) ins(lch , l , mid , L , R , q);
        if(mid < R) ins(rch , mid + 1 , r , L , R , q);
    }

    void ins(int x , int l , int r , int tar , modify m){
        mdy[x].push_back(m); if(l == r) return;
        mid >= tar ? ins(lch , l , mid , tar , m) : ins(rch , mid + 1 , r , tar , m);
    }
    
    void work(int x , int l , int r){
        Trie::cnt = 0; int rt = 0 , pos = 0;
        sort(mdy[x].begin() , mdy[x].end() , [&](modify A , modify B){return A.plc < B.plc;});
        sort(qry[x].begin() , qry[x].end() , [&](query A , query B){return A.R < B.R;});
        mdy[x].push_back((modify){(int)1e9 , 0});
        for(auto t : mdy[x]){
            while(pos < qry[x].size() && qry[x][pos].R < t.plc){
                if(qry[x][pos].id == 168)
                    qry[x][pos].id = 168;
                ans[qry[x][pos].id] = max(ans[qry[x][pos].id] , Trie::qry(rt , qry[x][pos].val , qry[x][pos].L));
                ++pos;
            } Trie::ins(rt , t.plc , t.num);
        }
        if(l != r){work(lch , l , mid); work(rch , mid + 1 , r);}
    }
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    N = read(); M = read(); rt[0] = 0;
    for(int i = 1 ; i <= N ; ++i) Trie::ins(rt[i] = rt[i - 1] , i , read());
    for(int i = 1 ; i <= M ; ++i)
        if(read()){
            int L = read() , R = read() , x = read() , d = read() , id = ++Q;
            if(d) segt::ins(1 , 0 , M , max(cnt - d + 1 , 0) , cnt , (query){L , R , x , id});
            ans[id] = max(ans[id] , Trie::qry(rt[R] , x , L));
        }
        else{
            int tms = ++cnt , plc = read() , val = read();
            segt::ins(1 , 0 , M , tms , (modify){plc , val});
        }
    segt::work(1 , 0 , M); for(int i = 1 ; i <= Q ; ++i) printf("%d\n" , ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Itst/p/11527262.html