[Luogu4848] 嶗山白花蛇草水 [動態開點權值線段樹&k-d tree]

[Link\frak{Link}]


我就不講了
claris kawaii %%%


主定理:假如每次分治得到 aa 個規模爲 1/b1/b 的問題並且需要 O(nd)O(n^d) 的額外計算
c=logbac=\log_ba 那麼複雜度爲 {Θ(nc),d<c,f(n)=O(nd){Θ(nc),k<1Θ(ncloglogn),k=1Θ(ndlogk+1n),k>1},f(n)=Θ(ndlogkn)Θ(f(n)),d>c\begin{cases} \Theta(n^c)&,d<c,f(n)=O(n^d)\\ \left\{\begin{array}{ll} \Theta(n^{c})&,k<-1\\ \Theta(n^{c}\log\log n)&,k=-1\\ \Theta(n^d\log^{k+1}n)&,k>-1\\ \end{array}\right\}&,f(n)=\Theta(n^d\log^kn)\\ \Theta(f(n))&,d>c\\ \end{cases}
(意會一下


複雜度 average ~ O(qlogv(log2n+n))O(q\log v(\log^2n+\sqrt n))
你問我 n\sqrt{n} 哪來的? kk-d tree 區間查詢(指常規的那種)的複雜度 O(kn11/k)O(kn^{1-1/k})
你問我 log2n\log^2n 哪來的?建樹的時候每層都要一次期望 O(logn)O(\log n) 的 nth_element
然後套主定理就可以解出來。


UPD:去掉結構體就飛了
也可能是我不小心改到了別的什麼?

nth_element因爲當時不知道是不是在這裏出錯 就學習了claris的錯誤寫法(
(窩跟隨了claris根據數據選擇不寫垃圾回收 快一點點

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<ctime>
#include<cmath>
using namespace std;
namespace fastIO{
    #define BUF_SIZE 100000
    #define OUT_SIZE 100000
    #define ll long long
    //fread->read
    bool IOerror=0;
    inline char nc(){
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
        if (p1==pend){
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
            if (pend==p1){IOerror=1;return -1;}
            //{printf("IO error!\n");system("pause");for (;;);exit(0);}
        }
        return *p1++;
    }
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline void read(int &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(ll &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(double &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (ch=='.'){
            double tmp=1; ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
        }
        if (sign)x=-x;
    }
    inline void read(char *s){
        char ch=nc();
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){
        for (c=nc();blank(c);c=nc());
        if (IOerror){c=-1;return;}
    }
    //getchar->read
    inline void read1(int &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (bo)x=-x;
    }
    inline void read1(ll &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (bo)x=-x;
    }
    inline void read1(double &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (ch=='.'){
            double tmp=1;
            for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
        }
        if (bo)x=-x;
    }
    inline void read1(char *s){
        char ch=getchar();
        for (;blank(ch);ch=getchar());
        for (;!blank(ch);ch=getchar())*s++=ch;
        *s=0;
    }
    inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
    //scanf->read
    inline void read2(int &x){scanf("%d",&x);}
    inline void read2(ll &x){
        #ifdef _WIN32
            scanf("%I64d",&x);
        #else
        #ifdef __linux
            scanf("%lld",&x);
        #else
            puts("error:can't recognize the system!");
        #endif
        #endif
    }
    inline void read2(double &x){scanf("%lf",&x);}
    inline void read2(char *s){scanf("%s",s);}
    inline void read2(char &c){scanf(" %c",&c);}
    inline void readln2(char *s){gets(s);}
    //fwrite->write
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        void out(char ch){
            if (p1==pend){
                fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
            }
            *p1++=ch;
        }
        void print(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(double x,int y){
            static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
                1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
                100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if (x<-1e-12)out('-'),x=-x;x*=mul[y];
            ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
            ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
            if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
        }
        void println(double x,int y){print(x,y);out('\n');}
        void print(char *s){while (*s)out(*s++);}
        void println(char *s){while (*s)out(*s++);out('\n');}
        void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(int x){Ostream.print(x);}
    inline void println(int x){Ostream.println(x);}
    inline void print(char x){Ostream.out(x);}
    inline void println(char x){Ostream.out(x);Ostream.out('\n');}
    inline void print(ll x){Ostream.print(x);}
    inline void println(ll x){Ostream.println(x);}
    inline void print(double x,int y){Ostream.print(x,y);}
    inline void println(double x,int y){Ostream.println(x,y);}
    inline void print(char *s){Ostream.print(s);}
    inline void println(char *s){Ostream.println(s);}
    inline void println(){Ostream.out('\n');}
    inline void flush(){Ostream.flush();}
    //puts->write
    char Out[OUT_SIZE],*o=Out;
    inline void print1(int x){
        static char buf[15];
        char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
        while(x)*p1++=x%10+'0',x/=10;
        while(p1--!=buf)*o++=*p1;
    }
    inline void println1(int x){print1(x);*o++='\n';}
    inline void print1(ll x){
        static char buf[25];
        char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
        while(x)*p1++=x%10+'0',x/=10;
        while(p1--!=buf)*o++=*p1;
    }
    inline void println1(ll x){print1(x);*o++='\n';}
    inline void print1(char c){*o++=c;}
    inline void println1(char c){*o++=c;*o++='\n';}
    inline void print1(char *s){while (*s)*o++=*s++;}
    inline void println1(char *s){print1(s);*o++='\n';}
    inline void println1(){*o++='\n';}
    inline void flush1(){if (o!=Out){if (*(o-1)=='\n')*--o=0;puts(Out);}}
    struct puts_write{
        ~puts_write(){flush1();}
    }_puts;
    inline void print2(int x){printf("%d",x);}
    inline void println2(int x){printf("%d\n",x);}
    inline void print2(char x){printf("%c",x);}
    inline void println2(char x){printf("%c\n",x);}
    inline void print2(ll x){
        #ifdef _WIN32
            printf("%I64d",x);
        #else
        #ifdef __linux
            printf("%lld",x);
        #else
            puts("error:can't recognize the system!");
        #endif
        #endif
    }
    inline void println2(ll x){print2(x);printf("\n");}
    inline void println2(){printf("\n");}
    #undef ll
    #undef OUT_SIZE
    #undef BUF_SIZE
};
using namespace fastIO;
const int MAXQ = 100010;
const int MAXV = 1e9;
const int MAXK = 1600010;
int n, q, cmp_d, tot, stktot;
int stk[MAXQ];
int Child[MAXK][2], Mn[MAXK][2], Mx[MAXK][2], Siz[MAXK], tmp[MAXQ];
int pox[MAXK], poy[MAXK];
int kRt[MAXK];
int sL[MAXK], sR[MAXK], segtot=1;
#define LChild(x) Child[x][0]
#define RChild(x) Child[x][1]
#define XMx(x) Mx[x][0]
#define XMn(x) Mn[x][0]
#define YMx(x) Mx[x][1]
#define YMn(x) Mn[x][1]
#define dx(g) pox[g]
#define dy(g) poy[g]
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define NewNode() ((++tot))
inline void setmin(int& a, const int& b) { if (b < a) a = b;}
inline void setmax(int& a, const int& b) { if (b > a) a = b;}
const double alph = 0.8;
inline void Maintain(const int& x)
{
    static int l, r;
    l = LChild(x), r = RChild(x);
    Siz[x] = Siz[l] + Siz[r] + 1;
    if (l)
    {
        setmax(XMx(x), XMx(l));
        setmin(XMn(x), XMn(l));
        setmax(YMx(x), YMx(l));
        setmin(YMn(x), YMn(l));
    }
    if (r)
    {
        setmax(XMx(x), XMx(r));
        setmin(XMn(x), XMn(r));
        setmax(YMx(x), YMx(r));
        setmin(YMn(x), YMn(r));
    }
}
void Pia(int Pos)
{
    if (LChild(Pos)) Pia(LChild(Pos)), LChild(Pos) = 0;
     stk[++stktot] = Pos;
    if (RChild(Pos)) Pia(RChild(Pos)), RChild(Pos) = 0;
}
inline bool cmpx(const int& a, const int& b) { return dx(a)<dx(b);}
inline bool cmpy(const int& a, const int& b) { return dy(a)<dy(b);}
int Structure(int L, int R, int Dim)
{
    int Mid = L + R >> 1, k;
    nth_element(stk+L+1, stk+Mid+1, stk+R+1, Dim?cmpy:cmpx);
    k = stk[Mid];
    XMn(k) = dx(k);
    XMx(k) = dx(k);
    YMn(k) = dy(k);
    YMx(k) = dy(k);
    if (L != Mid) LChild(k) = Structure(L, Mid - 1, !Dim);
    if (R != Mid) RChild(k) = Structure(Mid + 1, R, !Dim);
    Maintain(k);
    return k;
}
inline void Insert(int& Rt, const int& x, const int& y)
{
    static int Pos, Dim, k, fa;
    k = NewNode();
    XMn(k) = x;
    XMx(k) = x; 
    dx(k) = x;
    YMn(k) = y;
    YMx(k) = y;
    dy(k) = y;
    Siz[k] = 1;
    if (!Rt) { Rt = k; return;}
    Pos = Rt, Dim = 0, tmp[0] = 0;
    for(;;)
    {
        tmp[++tmp[0]] = Pos;
        setmax(XMx(Pos), x);
        setmin(XMn(Pos), x);
        setmax(YMx(Pos), y);
        setmin(YMn(Pos), y);
        ++Siz[Pos];
        if (!Dim)
        {
            if (dx(Pos) < x) { if (!LChild(Pos)) { LChild(Pos) = k; break;} Pos = LChild(Pos);}
            else { if (!RChild(Pos)) { RChild(Pos) = k; break;} Pos = RChild(Pos);}
        }
        else
        {
            if (dy(Pos) < y) { if (!LChild(Pos)) { LChild(Pos) = k; break;} Pos = LChild(Pos);}
            else { if (!RChild(Pos)) { RChild(Pos) = k; break;} Pos = RChild(Pos);}
        }
        Dim ^= 1;
    }
    tmp[++tmp[0]] = k;
    if (tmp[0] < log(Siz[Rt])/log(1/alph)) return;
    while (Siz[LChild(k)]<alph*Siz[k]&&Siz[RChild(k)]<alph*Siz[k]) 
    {
    	--tmp[0];
    	k = tmp[tmp[0]];
    }
    if (!k) return;
    if (k == Rt) { stktot = 0; Pia(k); Rt = Structure(1, stktot, 0); return;}
    fa = tmp[--tmp[0]];
    stktot = 0; Pia(k); 
    int tempemp = Structure(1, stktot, tmp[0]&1);
    if (RChild(fa)==k) RChild(fa)=tempemp;
    else LChild(fa)=tempemp;
//    Child[fa][RChild(fa)==k]=tempemp;
}
int Ans, x, y, xx, yy, k;
inline bool Declude(const int& Pos) { return XMx(Pos) < x || XMn(Pos) > xx || YMx(Pos) < y || YMn(Pos) > yy;}
inline bool Include(const int& Pos) { return XMx(Pos) <= xx && XMn(Pos) >= x && YMx(Pos) <= yy && YMn(Pos) >= y;}
inline bool In(const int& Pos) { return x<=dx(Pos)&&dx(Pos)<=xx&&y<=dy(Pos)&&dy(Pos)<=yy;}
inline void Count(int Pos)
{
    if (!Pos || Declude(Pos) || Ans >= k) return;
    if (Include(Pos)) { Ans += Siz[Pos]; return;}
    if (In(Pos)) ++Ans;
    Count(LChild(Pos));
    Count(RChild(Pos));
} 
inline void Query()
{
    Ans = 0; Count(kRt[1]);
    if (Ans < k) { Ans = 0; puts("NAIVE!ORZzyz."); return; }
    int L, Mid, R, Pos;
    L = 1; R = MAXV; Pos = 1;
    while (L < R)
    {
        Mid = L + R >> 1; Ans = 0; Count(kRt[sR[Pos]]);
        if (Ans >= k) Pos = sR[Pos], L = Mid + 1;
        else { k -= Ans; Pos = sL[Pos]; R = Mid;}
    }
    printf("%d\n", Ans = L);
}
inline void Add(const int& x, const int& y, const int& k)
{
    static bool Flag;
    static int t, L, R, Mid, Pos;
    
    Flag = 1; L = Pos = 1; R = MAXV;
    for(;;)
    {
        if (Flag) Insert(kRt[Pos], x, y);
        if (L >= R) return;
        Mid = L + R >> 1;
        if (k <= Mid)
        {
            if (!sL[Pos]) sL[Pos] = ++segtot;
            Pos = sL[Pos]; R = Mid; Flag = 0;
        }
        else
        {
            if (!sR[Pos]) sR[Pos] = ++segtot;
            Pos = sR[Pos]; L = Mid + 1; Flag = 1;
        }
    }
}
int main()
{
    read(q); read(q);
    int t;
    while (q--)
    {
    	read(t); read(x); read(y); x ^= Ans; y ^= Ans;
        if (t == 1) { read(k); k ^= Ans; Add(x, y, k);}
        else { read(xx); read(yy); read(k); xx ^= Ans; yy ^= Ans; k ^= Ans; Query();}
    }
    return 0;
}

下面是 92 分代碼

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<ctime>
#include<cmath>
using namespace std;
namespace fastIO{
    #define BUF_SIZE 100000
    #define OUT_SIZE 100000
    #define ll long long
    //fread->read
    bool IOerror=0;
    inline char nc(){
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
        if (p1==pend){
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
            if (pend==p1){IOerror=1;return -1;}
            //{printf("IO error!\n");system("pause");for (;;);exit(0);}
        }
        return *p1++;
    }
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline void read(int &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(ll &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(double &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (ch=='.'){
            double tmp=1; ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
        }
        if (sign)x=-x;
    }
    inline void read(char *s){
        char ch=nc();
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){
        for (c=nc();blank(c);c=nc());
        if (IOerror){c=-1;return;}
    }
    //getchar->read
    inline void read1(int &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (bo)x=-x;
    }
    inline void read1(ll &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (bo)x=-x;
    }
    inline void read1(double &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (ch=='.'){
            double tmp=1;
            for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
        }
        if (bo)x=-x;
    }
    inline void read1(char *s){
        char ch=getchar();
        for (;blank(ch);ch=getchar());
        for (;!blank(ch);ch=getchar())*s++=ch;
        *s=0;
    }
    inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
    //scanf->read
    inline void read2(int &x){scanf("%d",&x);}
    inline void read2(ll &x){
        #ifdef _WIN32
            scanf("%I64d",&x);
        #else
        #ifdef __linux
            scanf("%lld",&x);
        #else
            puts("error:can't recognize the system!");
        #endif
        #endif
    }
    inline void read2(double &x){scanf("%lf",&x);}
    inline void read2(char *s){scanf("%s",s);}
    inline void read2(char &c){scanf(" %c",&c);}
    inline void readln2(char *s){gets(s);}
    //fwrite->write
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        void out(char ch){
            if (p1==pend){
                fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
            }
            *p1++=ch;
        }
        void print(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(double x,int y){
            static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
                1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
                100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if (x<-1e-12)out('-'),x=-x;x*=mul[y];
            ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
            ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
            if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
        }
        void println(double x,int y){print(x,y);out('\n');}
        void print(char *s){while (*s)out(*s++);}
        void println(char *s){while (*s)out(*s++);out('\n');}
        void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(int x){Ostream.print(x);}
    inline void println(int x){Ostream.println(x);}
    inline void print(char x){Ostream.out(x);}
    inline void println(char x){Ostream.out(x);Ostream.out('\n');}
    inline void print(ll x){Ostream.print(x);}
    inline void println(ll x){Ostream.println(x);}
    inline void print(double x,int y){Ostream.print(x,y);}
    inline void println(double x,int y){Ostream.println(x,y);}
    inline void print(char *s){Ostream.print(s);}
    inline void println(char *s){Ostream.println(s);}
    inline void println(){Ostream.out('\n');}
    inline void flush(){Ostream.flush();}
    //puts->write
    char Out[OUT_SIZE],*o=Out;
    inline void print1(int x){
        static char buf[15];
        char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
        while(x)*p1++=x%10+'0',x/=10;
        while(p1--!=buf)*o++=*p1;
    }
    inline void println1(int x){print1(x);*o++='\n';}
    inline void print1(ll x){
        static char buf[25];
        char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
        while(x)*p1++=x%10+'0',x/=10;
        while(p1--!=buf)*o++=*p1;
    }
    inline void println1(ll x){print1(x);*o++='\n';}
    inline void print1(char c){*o++=c;}
    inline void println1(char c){*o++=c;*o++='\n';}
    inline void print1(char *s){while (*s)*o++=*s++;}
    inline void println1(char *s){print1(s);*o++='\n';}
    inline void println1(){*o++='\n';}
    inline void flush1(){if (o!=Out){if (*(o-1)=='\n')*--o=0;puts(Out);}}
    struct puts_write{
        ~puts_write(){flush1();}
    }_puts;
    inline void print2(int x){printf("%d",x);}
    inline void println2(int x){printf("%d\n",x);}
    inline void print2(char x){printf("%c",x);}
    inline void println2(char x){printf("%c\n",x);}
    inline void print2(ll x){
        #ifdef _WIN32
            printf("%I64d",x);
        #else
        #ifdef __linux
            printf("%lld",x);
        #else
            puts("error:can't recognize the system!");
        #endif
        #endif
    }
    inline void println2(ll x){print2(x);printf("\n");}
    inline void println2(){printf("\n");}
    #undef ll
    #undef OUT_SIZE
    #undef BUF_SIZE
};
using namespace fastIO;
const int MAXQ = 100005;
const int MAXV = 1e9;
const int MAXK = MAXQ*50;
const int MAXN = MAXQ*5;
int n, q, cmp_d, tot, stktot;
struct pt
{
    int x, y;
    pt(int a=0, int b=0) { x = a, y = b;}
}KTp[MAXK], stk[MAXN];
int Child[MAXK][2], Mn[MAXK][2], Mx[MAXK][2], Siz[MAXK], tmp[MAXK];
int kRt[MAXK];
int sL[MAXK], sR[MAXK], segtot=1;
#define LChild(x) Child[x][0]
#define RChild(x) Child[x][1]
#define XMx(x) Mx[x][0]
#define XMn(x) Mn[x][0]
#define YMx(x) Mx[x][1]
#define YMn(x) Mn[x][1]
#define dx(g) KTp[g].x
#define dy(g) KTp[g].y
#define Pt(x) KTp[x]
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define NewNode() ((++tot))
inline void setmin(int& a, const int& b) { if (b < a) a = b;}
inline void setmax(int& a, const int& b) { if (b > a) a = b;}
const double alph = 0.8;
const double lalph = (1.0/log(1/alph));
inline void Maintain(const int& x)
{
	static int l, r;
    l = LChild(x), r = RChild(x);
    Siz[x] = Siz[l] + Siz[r] + 1;
    if (l)
    {
        setmax(XMx(x), XMx(l));
        setmin(XMn(x), XMn(l));
        setmax(YMx(x), YMx(l));
        setmin(YMn(x), YMn(l));
    }
    if (r)
    {
        setmax(XMx(x), XMx(r));
        setmin(XMn(x), XMn(r));
        setmax(YMx(x), YMx(r));
        setmin(YMn(x), YMn(r));
    }
}
void Pia(int Pos)
{
    if (LChild(Pos)) Pia(LChild(Pos)), LChild(Pos) = 0;
    kClear(Pos); stk[++stktot] = Pt(Pos);
    if (RChild(Pos)) Pia(RChild(Pos)), RChild(Pos) = 0;
}
inline bool cmpx(const pt& a, const pt& b) { return a.x<b.x;}
inline bool cmpy(const pt& a, const pt& b) { return a.y<b.y;}
int Structure(int L, int R, int Dim)
{
    int Mid = L + R >> 1, k;
    nth_element(stk+L, stk+Mid, stk+R+1, Dim?cmpy:cmpx);
    Pt(k=NewNode()) = stk[Mid];
    XMn(k) = XMx(k) = dx(k);
    YMn(k) = YMx(k) = dy(k);
    if (L != Mid) LChild(k) = Structure(L, Mid - 1, !Dim);
    if (R != Mid) RChild(k) = Structure(Mid + 1, R, !Dim);
    Maintain(k);
    return k;
}
void Insert(int& Rt, const int& x, const int& y)
{
    static int Pos, Dim, k, fa;
    Pos = Rt, Dim = 0, k = NewNode();
    XMn(k) = XMx(k) = dx(k) = x;
    YMn(k) = YMx(k) = dy(k) = y;
    Siz[k] = 1;
    if (!Rt) { Rt = k; return;}
    tmp[0] = 0;
    for(;;)
    {
        tmp[++tmp[0]] = Pos;
        setmax(XMx(Pos), x);
        setmin(XMn(Pos), x);
        setmax(YMx(Pos), y);
        setmin(YMn(Pos), y);
        ++Siz[Pos];
        if (!Dim)
        {
            if (dx(Pos) < x) { if (!LChild(Pos)) { LChild(Pos) = k; break;} Pos = LChild(Pos);}
            else { if (!RChild(Pos)) { RChild(Pos) = k; break;} Pos = RChild(Pos);}
        }
        else
        {
            if (dy(Pos) < y) { if (!LChild(Pos)) { LChild(Pos) = k; break;} Pos = LChild(Pos);}
            else { if (!RChild(Pos)) { RChild(Pos) = k; break;} Pos = RChild(Pos);}
        }
        Dim = !Dim;
    }
    tmp[++tmp[0]] = k;
	if (1.0*tmp[0] < lalph*log(Siz[Rt])) return;
    while ((max(Siz[LChild(k)],Siz[RChild(k)])<<2)<5*Siz[k]) k = tmp[--tmp[0]];
    if (!k) return; if (k == Rt) { stktot = 0; Pia(k); Rt = Structure(1, stktot, 0); return;}
    fa = tmp[--tmp[0]]; stktot = 0; Pia(k); Child[fa][RChild(fa)==k]=Structure(1, stktot, tmp[0]&1);
}
int Ans, x, y, xx, yy, k;
inline bool Declude(const int& Pos) { return XMx(Pos) < x || XMn(Pos) > xx || YMx(Pos) < y || YMn(Pos) > yy;}
inline bool Include(const int& Pos) { return XMx(Pos) <= xx && XMn(Pos) >= x && YMx(Pos) <= yy && YMn(Pos) >= y;}
inline bool In(const int& Pos) { return x<=dx(Pos)&&dx(Pos)<=xx&&y<=dy(Pos)&&dy(Pos)<=yy;}
inline void Count(int Pos)
{
    if (!Pos || Declude(Pos) || Ans >= k) return;
    if (Include(Pos)) { Ans += Siz[Pos]; return;}
    if (In(Pos)) ++Ans;
    Count(LChild(Pos));
    Count(RChild(Pos));
} 
inline void Query()
{
    static int L, Mid, R, Pos;
    Ans = 0; Count(kRt[1]);
    if (Ans < k) { Ans = 0; puts("NAIVE!ORZzyz."); return; }
    L = 1; R = MAXV; Pos = 1;
    while (L < R)
    {
        Mid = L + R >> 1; Ans = 0; Count(kRt[sR[Pos]]);
        if (Ans >= k) Pos = sR[Pos], L = Mid + 1;
        else { k -= Ans; Pos = sL[Pos]; R = Mid;}
    }
    printf("%d\n", Ans = L);
}
inline void Add(const int& x, const int& y, const int& k)
{
    static bool Flag;
    static int t, L, R, Mid, Pos;
    
    Flag = 1; L = Pos = 1; R = MAXV;
    for(;;)
    {
        if (Flag) Insert(kRt[Pos], x, y);
        if (L >= R) return;
        Mid = L + R >> 1;
        if (k <= Mid)
        {
            if (!sL[Pos]) sL[Pos] = ++segtot;
            Pos = sL[Pos]; R = Mid; Flag = 0;
        }
        else
        {
            if (!sR[Pos]) sR[Pos] = ++segtot;
            Pos = sR[Pos]; L = Mid + 1; Flag = 1;
        }
    }
}
int main()
{
    read(n); read(q);
    int t;
    while (q--)
    {
    	read(t); read(x); read(y); x ^= Ans; y ^= Ans;
        if (t == 1) { read(k); k ^= Ans; Add(x, y, k);}
        else { read(xx); read(yy); read(k); xx ^= Ans; yy ^= Ans; k ^= Ans; Query();}
    }
    return 0;
}

這是我第一次碼這道題的時候
我當時第一發 92 以爲就要 accepted
沒想到 nb嗷

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<ctime>
#include<cmath>
using namespace std;
const int MAXQ = 100005;
const int MAXV = 1e9;
const int MAXK = MAXQ*40;
const int MAXN = MAXQ*5;
int n, q, cmp_d, tot, stktot;
struct pt
{
    int x, y;
    pt(int a=0, int b=0) { x = a, y = b;}
}KTp[MAXK], stk[MAXN];
int Child[MAXK][2], Mn[MAXK][2], Mx[MAXK][2], Siz[MAXK], tmp[MAXN], rBin[MAXN];
int kRt[MAXK];
int sL[MAXK], sR[MAXK], segtot=1;
#define LChild(x) Child[x][0]
#define RChild(x) Child[x][1]
#define XMx(x) Mx[x][0]
#define XMn(x) Mn[x][0]
#define YMx(x) Mx[x][1]
#define YMn(x) Mn[x][1]
#define dx(g) KTp[g].x
#define dy(g) KTp[g].y
#define Pt(x) KTp[x]
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define setmin(a,b) ((b)<(a)?((a)=(b)):0)
#define setmax(a,b) ((b)>(a)?((a)=(b)):0)
#define kClear(t) XMx(t)=YMx(t)=dx(t)=dy(t)=Siz[t]=0,XMn(t)=YMn(t)=0x3f3f3f3f
#define NewNode() ((rBin[0])?(rBin[0]--):(++tot))
void coucou (const int& k)
{
    cout<<k<<" L"<<LChild(k)<<" R"<<RChild(k)<<" X"<<XMn(k)<<"~"<<dx(k)<<"~"<<XMx(k)<< " Y"<<YMn(k)<<"~"<<dy(k)<<"~"<<YMx(k)<<" siz"<<Siz[k]<<endl;
}
const double alph = 0.8;
const double lalph = log(1/alph);
inline void Maintain(const int& x)
{
    static int l, r;
    
    l = LChild(x); r = RChild(x);
    Siz[x] = Siz[l] + Siz[r] + 1;
    if (l)
    {
        setmax(XMx(x), XMx(l));
        setmin(XMn(x), XMn(l));
        setmax(YMx(x), YMx(l));
        setmin(YMn(x), YMn(l));
    }
    if (r)
    {
        setmax(XMx(x), XMx(r));
        setmin(XMn(x), XMn(r));
        setmax(YMx(x), YMx(r));
        setmin(YMn(x), YMn(r));
    }
}
void Pia(int Pos)
{
    if (LChild(Pos)) Pia(LChild(Pos)), LChild(Pos) = 0;
    kClear(Pos); stk[++stktot] = Pt(Pos); rBin[++rBin[0]] = Pos;
    if (RChild(Pos)) Pia(RChild(Pos)), RChild(Pos) = 0;
}
bool cmpx(const pt& a, const pt& b) { return a.x<b.x;}
bool cmpy(const pt& a, const pt& b) { return a.y<b.y;}
int Structure(int L, int R, int Dim)
{
    int Mid = L + R >> 1, k;
    nth_element(stk+L, stk+Mid, stk+R+1, Dim?cmpy:cmpx);
    Pt(k=NewNode()) = stk[Mid];
    XMn(k) = XMx(k) = dx(k);
    YMn(k) = YMx(k) = dy(k);
    if (L != Mid) LChild(k) = Structure(L, Mid - 1, !Dim);
    if (R != Mid) RChild(k) = Structure(Mid + 1, R, !Dim);
    Maintain(k);
    return k;
}
void Insert(int& Rt, const int& x, const int& y)
{
    static int Pos, Dim, k, fa;
    
    Pos = Rt, Dim = 0, k = NewNode();
    XMn(k) = XMx(k) = dx(k) = x;
    YMn(k) = YMx(k) = dy(k) = y;
    Siz[k] = 1;
    if (!Rt) { Rt = k; return;}
    tmp[0] = 0;
    while (true) 
    {
        tmp[++tmp[0]] = Pos;
        setmax(XMx(Pos), x);
        setmin(XMn(Pos), x);
        setmax(YMx(Pos), y);
        setmin(YMn(Pos), y);
        ++Siz[Pos];
        if (!Dim)
        {
            if (dx(Pos) <= x) { if (!LChild(Pos)) { LChild(Pos) = k; break;} Pos = LChild(Pos);}
            else { if (!RChild(Pos)) { RChild(Pos) = k; break;} Pos = RChild(Pos);}
        }
        else
        {
            if (dy(Pos) <= y) { if (!LChild(Pos)) { LChild(Pos) = k; break;} Pos = LChild(Pos);}
            else { if (!RChild(Pos)) { RChild(Pos) = k; break;} Pos = RChild(Pos);}
        }
        Dim = !Dim;
    }
    tmp[++tmp[0]] = k;
    if (1.0*tmp[0] < log(Siz[Rt]) / lalph) return;
    while (alph*Siz[LChild(k)]<Siz[k] && alph*Siz[RChild(k)]<Siz[k]) k = tmp[--tmp[0]];
    if (!k) return;
    if (k == Rt)
    {
        Rt = k; stktot = 0; Pia(k);
        Rt = Structure(1, stktot, 0);
        return;
    }
    fa = tmp[--tmp[0]];
    stktot = 0; Pia(k);
    Pos = Structure(1, stktot, tmp[0]&1);
    Child[fa][RChild(fa)==k]=Pos;
}
int Ans;
void Count(int Pos, const int& x, const int& y, const int& xx, const int& yy, const int& k)
{
    if (!Pos || XMx(Pos) < x || XMn(Pos) > xx || YMx(Pos) < y || YMn(Pos) > yy || Ans >= k) return;
    if (XMx(Pos) <= xx && XMn(Pos) >= x && YMx(Pos) <= yy && YMn(Pos) >= y) { Ans += Siz[Pos]; return;}
    if (x<=dx(Pos)&&dx(Pos)<=xx&&y<=dy(Pos)&&dy(Pos)<=yy) ++Ans;
    Count(LChild(Pos), x, y, xx, yy, k);
    Count(RChild(Pos), x, y, xx, yy, k);
} 
void Query(const int& xin, const int& yin, const int& xax, const int& yax, int k)
{
    static int L, Mid, R, Pos;
    Ans = 0;
    Count(kRt[1], xin, yin, xax, yax, k);
    if (Ans < k)
    {
        Ans = 0;
        puts("NAIVE!ORZzyz.");
        return;
    }
    L = 1;
    R = MAXV;
    Pos = 1;
    while (L < R)
    {
        Mid = L + R >> 1;
        Ans = 0;
        Count(kRt[sR[Pos]], xin, yin, xax, yax, k);
        if (Ans >= k) Pos = sR[Pos], L = Mid + 1;
        else
        {
            k -= Ans;
            Pos = sL[Pos];
            R = Mid;
        }
    }
    printf("%d\n", Ans = L);
}
void Add(const int& x, const int& y, const int& k)
{
    static bool Flag;
    static int t, L, R, Mid, Pos;
    
    Flag = 1;
    L = 1;
    R = MAXV;
    Pos = 1;
    while (true)
    {
        if (Flag) Insert(kRt[Pos], x, y);
        if (L == R) return;
        Mid = L + R >> 1;
        if (k <= Mid)
        {
            if (!sL[Pos]) sL[Pos] = ++segtot;
            Pos = sL[Pos];
            R = Mid;
            Flag = 0;
        }
        else
        {
            if (!sR[Pos]) sR[Pos] = ++segtot;
            Pos = sR[Pos];
            L = Mid + 1;
            Flag = 1;
        }
    }
}
int main()
{
    memset(Mn,0x3f,sizeof(Mn));
    scanf("%d%d", &n, &q);
    for (register int t, x, y, xx, yy, k, i = 1; i <= q; ++i)
    {
        scanf("%d%d%d", &t, &x, &y);
        x ^= Ans; y ^= Ans;
        if (t == 1)
        {
            scanf("%d", &k);
            k ^= Ans;
            Add(x, y, k);
        }
        else
        {
            scanf("%d%d%d", &xx, &yy, &k);
            xx ^= Ans; yy ^= Ans; k ^= Ans;
            Query(x, y, xx, yy, k);
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章