[5795] Luo Valley [THUSC2015] exclusive OR operation (persistence-Trie)

Click here to see the problem surface

Generally meaning of the questions: Given a length \ (n-\) sequence \ (x_ {1 \ sim n } \) and a length \ (m \) sequence \ (Y_ {. 1 \ SIM m} \) , matrix \ (a \) first \ (I \) row \ (J \) element column \ (A_ {I, J} = x_i \ XOR \ y_j \) , each query satisfies the matrix row number \ ( i∈ [U, D] \) , the column number \ (j∈ [l, r] \) of the first sub-matrix \ (K \) large elements.

Two \ (log \) approach

First, we can have a complexity of an inferior two \ (log \) approach: be persistent dichotomy + \ (Trie \) .

For consider the sequence \ (y \) to build a sustainable technology \ (Trie \) .

Then, we dichotomous answer \ (MID \) .

Next, enumerate each row (note that the number of lines less), is obtained for each row equal to greater than \ (MID \) the counted number of.

The number of these add up to, if not less than \ (k \) , explained the answer \ (mid \) legitimate and continue half a larger answer, otherwise the smaller half of the answer.

The two (log \) \ approach should be quite simple.

Optimization Practices

In (XZY \) \ under the guidance of the gods, I know how to put this approach is optimized for a \ (log \) .

We can make these lines of inquiry together in persistable \ (Trie \) run on each line corresponding to each note of the current node.

Then descending to enumerate every one, all the lines for which statistics one can have is \ (1 \) number.

If this number is greater than equal to \ (k \) , it shows that one can \ (1 \) , otherwise, the bit is \ (0 \) .

Code

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000
#define M 300000
using namespace std;
int n,m,a[N+5],b[M+5];
class FastIO
{
    private:
        #define FS 100000
        #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
        #define tn (x<<3)+(x<<1)
        #define D isdigit(c=tc())
        char c,*A,*B,FI[FS];
    public:
        I FastIO() {A=B=FI;}
        Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
        Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
class ChairmanTrie
{
    private:
        int T;struct node {int Sz;node* S[2];I node() {Sz=0,S[0]=S[1]=NULL;}}*Rt[M+5],*l[N+5],*r[N+5];
        #define Sz(x) (x==NULL?0:x->Sz)
        #define S(x,d) (x==NULL?NULL:x->S[d])
        I void Ins(node*& rt,node* lst,CI x,CI d)//插入
        {
            rt=new node,rt->Sz=Sz(lst),rt->S[0]=S(lst,0),rt->S[1]=S(lst,1);
            if(++rt->Sz,!~d) return;int t=(x>>d)&1;Ins(rt->S[t],S(lst,t),x,d-1);
        }
        I int Qry(CI s,CI t,CI k,CI d)//询问
        {
            if(!~d) return 0;RI i,tot=0;
            for(i=s;i<=t;++i) tot+=Sz(S(r[i],(a[i]>>d)&1^1))-Sz(S(l[i],(a[i]>>d)&1^1));//统计能有的1的个数
            if(tot>=k)//如果个数大于等于k,说明这一位能填1
            {
                for(i=s;i<=t;++i) l[i]=S(l[i],(a[i]>>d)&1^1),r[i]=S(r[i],(a[i]>>d)&1^1);
                return Qry(s,t,k,d-1)|(1<<d);
            }
            else//否则填0
            {
                for(i=s;i<=t;++i) l[i]=S(l[i],(a[i]>>d)&1),r[i]=S(r[i],(a[i]>>d)&1);
                return Qry(s,t,k-tot,d-1);
            }
        }
    public:
        I ChairmanTrie() {for(RI i=1;i<=N;++i) Rt[i]=NULL;}
        I void Ins(CI v,CI v_,CI x) {Ins(Rt[v],Rt[v_],x,30);}
        I int Qry(CI vl,CI vr,CI s,CI t,CI k)
        {
            for(RI i=s;i<=t;++i) l[i]=Rt[vl-1],r[i]=Rt[vr];return Qry(s,t,k,30);//初始化每一行所对应的节点为根节点
        }
}T;
int main()
{
    RI Qt,i,u,d,x,y,k,l,r,mid,t;F.read(n),F.read(m);
    for(i=1;i<=n;++i) F.read(a[i]);for(i=1;i<=m;++i) F.read(b[i]),T.Ins(i,i-1,b[i]);//初始化可持久化Trie
    F.read(Qt);W(Qt--) F.read(u,d,x,y,k),printf("%d\n",T.Qry(x,y,u,d,k));return 0;//处理询问
}

Guess you like

Origin www.cnblogs.com/chenxiaoran666/p/Luogu5795.html