BZOJ 4942: [Noi2017] segment tree integer ZKW

title

\ (~ \)
BZOJ 4942
LUOGU 3822
entitled to engage in simpler:

There is an integer \ (the X-\) , a start \ (0 \) .
Then there \ (n-\) operations, each operation being one of two types:
. 1 ab &: the \ (X \) plus integer \ (A \ B ^ CDOT 2 \) , wherein \ (a \) is an integer, \ (B \) is a non-negative integer
2 k: Inquiry \ (X \) when expressed in binary, the bit weight is \ (2 ^ k \) of the value of the bit (i.e., it on a \ (1 \) represents the \ (2 ^ k \) )
to ensure that at all times, \ (the X-\ geqslant 0 \) .
\ (1 \ leqslant n \ leqslant10 ^ 6, | a | \ leqslant 10 ^ 9,0 \ leqslant b, k \ leqslant 30n \)

analysis

Consider violence, we opened two arrays to simulate the carry (one is \ (A> 0 \) , another \ (A <0 \) ).

The inquiry, we assume that less than \ (K \) bit portion \ (a> 0 \) is \ (S1 \) , \ (A <0 \) is \ (S2 \) .

Discussion of all cases, we can conclude:

  1. If \ (S1 \ geqslant S2 \) , output answer is \ ([x⊕y] \) , where \ (X \) is the \ (a> 0 \) of the \ (K \) value of a bit, \ ( Y \) is (a <0 \) \ section \ (K \) value of the bit.
  2. If \ (S1 <S2 \) , output answer is \ ([X = Y] \) .
    Such overall complexity is \ (O (30nlog (30n) ) \) a.

Complexity seems to have gifted enough, consider optimizing.
What to consider it, take a direct Black & \ (zkw segment tree \) card in the past it!

Of course, such a fast hardware \ (zkw segment tree \) I can not think pressure level segment tree was not any effort to learn, but for learning the NaVi_Awson of \ (Blog \) , I have to write that close \ (200 + \) the \ (code \) a.

By the way, \ (BZOJ \) does not recognize this thing on, kill me.

putchar('0'+(s1[a]^s2[a]));

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6,maxm=maxn*30+300;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x)
{
    if (!x) *fe++=48;
    if (x<0) *fe++='-', x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) *fe++=ch[num--];
    *fe++='\n';
}

int s1[maxm],s2[maxm],t[(1<<26)+5],lst[32],bin[32],N;
inline void Change(int *s,int a,int b)
{
    int tot=0;
    for (int i=30; i>=0 && a; --i)
        if (bin[i]&a) lst[++tot]=i,a-=bin[i];
    int l=lst[tot]+b,r=lst[1]+b;
    for (int i=1; i<=tot; ++i)
    {
        int now=lst[i]+b;
        while (s[now]) s[now++]=0;
        r=max(r,now),s[now]=1;
    }
    for (int i=l; i<=r; ++i) t[i+N]=(s1[i]^s2[i]);
    for (l=(l+N)>>1,r=(r+N)>>1; l; l>>=1,r>>=1)
        for (int i=l; i<=r; ++i) t[i]=t[i<<1]|t[i<<1|1];
}

inline int query(int a)
{
    for (a+=N; a; a>>=1)
        if (a&1&t[a^1])
        {
            for (a^=1; a<N; a=a<<1|t[a<<1|1]);
            return a-N;
        }
    return -1;
}

int main()
{
    int n,t1;read(n);read(t1),read(t1),read(t1);
    for (N=1; N<=n*30; N<<=1);
    bin[0]=1;
    for (int i=1; i<=30; ++i) bin[i]=(bin[i-1]<<1);
    while (n--)
    {
        int opt,a,b;read(opt);
        if (opt==1)
        {
            read(a);read(b);
            if (a<0) Change(s2,-a,b);
            else Change(s1,a,b);
        }
        else
        {
            read(a);int now=query(a);
            if (now==-1 || s1[now]>s2[now]) write((int)(s1[a]^s2[a]));
            else write((int)(s1[a]==s2[a]));
        }
    }
    flush();
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11318072.html