求卡常方法 qwq
查看原帖
求卡常方法 qwq
305891
Eraine楼主2024/6/13 17:06

用的是外层权值线段树,内层 K-D Tree 的写法。内层 K-D Tree 更新用的是二进制分组重构。

实在卡不过去,恳求大佬提供个卡常方法 /kel

#8 在本地实测 20s

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
const int Q=1e5+5;
const int B=20;
const int inf=1e9;
int n,m,k,ans;
vector<int>L(2),R(2),val(2);
namespace KDT{
    int idx=0;
    int cmptype;
    stack<int>S;
    struct Point{
        vector<int>x;
        inline friend bool operator<(Point A,Point B){
            return A.x[cmptype]<B.x[cmptype];
        }
    }a[Q];
    int p;
    /*
    notice to clear p !!!
    */
    struct node{
        int ch[2];
        int sum;
        vector<int>l,r,x;
    }tr[Q<<5];
    struct KDTree{
        #define lc tr[i].ch[0]
        #define rc tr[i].ch[1]
        #define mid (l+r)/2
        inline int newnode(){
            if(!S.empty()){
                int x=S.top();
                S.pop();
                return x;
            }
            return ++idx;
        }
        void build(int &i,int l,int r,int type){
            if(l>r){
                i=0;
                return;
            }
            i=newnode();
            if(l<r){
                cmptype=type;
                nth_element(a+l,a+mid,a+r+1);
            }
            int lst=R[type];
            R[type]=a[mid].x[type];
            build(lc,l,mid-1,type^1);
            R[type]=lst;
            lst=L[type];
            L[type]=a[mid].x[type];
            build(rc,mid+1,r,type^1);
            L[type]=lst;
            tr[i].l=a[mid].x,tr[i].r=a[mid].x,tr[i].x=a[mid].x;
            if(lc){
                tr[i].l[0]=min(tr[i].l[0],tr[lc].l[0]);
                tr[i].l[1]=min(tr[i].l[1],tr[lc].l[1]);
                tr[i].r[0]=max(tr[i].r[0],tr[lc].r[0]);
                tr[i].r[1]=max(tr[i].r[1],tr[lc].r[1]);
            }
            if(rc){
                tr[i].l[0]=min(tr[i].l[0],tr[rc].l[0]);
                tr[i].l[1]=min(tr[i].l[1],tr[rc].l[1]);
                tr[i].r[0]=max(tr[i].r[0],tr[rc].r[0]);
                tr[i].r[1]=max(tr[i].r[1],tr[rc].r[1]);
            }
            tr[i].sum=r-l+1;
        }
        void flatten(int i){
            if(!i){
                return;
            }
            a[++p].x=tr[i].x;
            S.push(i);
            flatten(lc);
            flatten(rc);
        }
        int query(int i){
            if(!i){
                return 0;
            }
            auto check1=[&](){
                for(register int d=0;d<2;d++){
                    if(R[d]<tr[i].l[d]){
                        return 0;
                    }
                    if(L[d]>tr[i].r[d]){
                        return 0;
                    }
                }
                return 1;
            };
            if(!check1()){
                return 0;
            }
            auto check2=[&](){
                for(register int d=0;d<2;d++){
                    if(L[d]>tr[i].l[d]){
                        return 0;
                    }
                    if(R[d]<tr[i].r[d]){
                        return 0;
                    }
                }
                return 1;
            };
            if(check2()){
                return tr[i].sum;
            }
            auto check3=[&](){
                for(register int d=0;d<2;d++){
                    if(L[d]>tr[i].x[d]){
                        return 0;
                    }
                    if(R[d]<tr[i].x[d]){
                        return 0;
                    }
                }
                return 1;
            };
            int res=0;
            if(check3()){
                ++res;
            }
            res=res+query(lc);
            res=res+query(rc);
            return res;
        }
        #undef lc
        #undef rc
        #undef mid
    }kdt;
}
using namespace KDT;
namespace SGT{
    struct node{
        int ch[2];
        int rt[20];
    }tr[Q<<5];
    int idx;
    struct SGTree{
        #define lc tr[i].ch[0]
        #define rc tr[i].ch[1]
        #define mid (l+r)/2
        void modify(int &i,int l,int r,int x){
            if(!i){
                i=++idx;
            }
            p=0;
            a[++p].x=val;
            for(int j=0;j<B;j++){
                if(!tr[i].rt[j]){
                    L=vector<int>(2,1);
                    R=vector<int>(2,n);
                    kdt.build(tr[i].rt[j],1,p,0);
                    break;
                }else{
                    kdt.flatten(tr[i].rt[j]);
                    tr[i].rt[j]=0;
                }
            }
            if(l==r){
                return;
            }
            if(x<=mid){
                modify(lc,l,mid,x);
            }else{
                modify(rc,mid+1,r,x);
            }
        }
        inline int getsum(int i){
            if(!i){
                return 0;
            }
            int res=0;
            for(register int j=0;j<B;j++){
                if(!tr[i].rt[j]){
                    continue;
                }
                res=res+kdt.query(tr[i].rt[j]);
            }
            return res;
        }
        void query(int i,int l,int r){
            if(!i){
                return;
            }
            int val;
            if(l==r){
                val=getsum(i);
                k=k-min(k,val);
                ans=l;
                return;
            }
            if(!lc){
                query(rc,mid+1,r);
                return;
            }
            if(!rc){
                query(lc,l,mid);
                return;
            }
            val=getsum(rc);
            if(k<=val){
                query(rc,mid+1,r);
            }else{
                k=k-val;
                query(lc,l,mid);
            }
        }
        #undef lc
        #undef rc
        #undef mid
    }sgt;
}
using namespace SGT;
inline int read(){
    int x=0,f=1;
    char c=getchar();
    while(!isdigit(c)){
        if(c=='-'){
            f=-1;
        }
        c=getchar();
    }
    while(isdigit(c)){
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    }
    return x*f;
}
int rt;
int main(){
    n=read(),m=read();
    int lastans=0;
    for(int i=1;i<=m;i++){
        int type=read();
        int v;
        if(type==1){
            val[0]=read()^lastans,val[1]=read()^lastans,v=read()^lastans;
            sgt.modify(rt,1,inf,v);
        }else if(type==2){
            L[0]=read()^lastans,L[1]=read()^lastans,R[0]=read()^lastans,R[1]=read()^lastans,k=read()^lastans;
            ans=inf;
            sgt.query(rt,1,inf);
            if(k>0){
                lastans=0;
                printf("NAIVE!ORZzyz.\n");
            }else{
                printf("%d\n",lastans=ans);
            }
        }
    }
    return 0;
}
2024/6/13 17:06
加载中...