个人代码基础模板

· · 算法·理论

Aurelia_Veil 好菜呀

欧拉回路

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+111;
int n,m;
vector<int>g[N];
stack<int>ans;
int in[N],out[N];
int thi[N];
void FC(int u){
    for(int i=thi[u];i<g[u].size();i=thi[u]){
        int v=g[u][i];
        thi[u]=i+1;
        FC(v);
    }
    ans.push(u);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        in[y]++;
        out[x]++;
        g[x].push_back(y);
    }
    int cntin=0,cntout=0,top=1;
    for(int i=1;i<=n;i++){
        if(abs(in[i]-out[i])>=2){
            printf("No");
            return 0;
        }
        if(in[i]==out[i]+1){
            cntin++;
        }
        if(in[i]+1==out[i]){
            top=i;
            cntout++;
        }
    }
    if(cntin>=2||cntout>=2){
        printf("No");
        return 0;
    }
    for(int i=1;i<=n;i++){
        sort(g[i].begin(),g[i].end());
    }
    FC(top);
    while(!ans.empty()){
        printf("%d ",ans.top());
        ans.pop();
    }
    return 0;
}

快读快写

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define itn int
#define fro for
#define scnaf scanf
#define snacf scanf
#define prinf printf
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
inline string readS(){
    string s;
    char ch=getchar();
    while(ch==' '||ch=='\n'){
        ch=getchar();
    }
    while(ch!=' '&&ch!='\n'){
        s+=ch;
        ch=getchar();
    }
    return s;
}
inline string readSL(){
    string s;
    s.clear();
    char ch=getchar();
    while(ch=='\n'){
        ch=getchar();
    }
    while(ch!='\n'){
        s+=ch;
        ch=getchar();
    }
    return s;
}
inline void readC(char s[]){
    int tot=0;
    char ch=getchar();
    while(ch==' '||ch=='\n'){
        ch=getchar();
    }
    while(ch!=' '&&ch!='\n'){
        s[tot++]=ch;
        ch=getchar();
    }
}
inline char readc(){
    char c=getchar();
    while(c==' '||c=='\n'){
        c=getchar();
    }
    return c;
}
inline void write(int x){
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9){
        write(x/10);
    }
    putchar(x%10+'0');
    return;
}
inline void writeS(string x){
    int len=x.length();
    for(int i=0;i<len;++i){
        putchar(char(x[i]));
    }
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    return 0;
}
#include<bits/stdc++.h>
#include<unistd.h>
using namespace std;
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
constexpr int BUFSIZE=1<<14; 
char ibuf[BUFSIZE],*ibg=ibuf+BUFSIZE,obuf[BUFSIZE],*obg=obuf;
const char *ied=ibuf+BUFSIZE,*oed=obuf+BUFSIZE;
#define INLINE inline __attribute__ ((always_inline))
//INLINE char get(){
//  if(ibg==ied){
//      cin.read(ibg=ibuf,BUFSIZE);
//  }
//  return *ibg++; 
//} 
INLINE void put(char a){
    if(obg==oed){
        write(1,obg=obuf,BUFSIZE);
    }
    *(obg++)=a;
} 
INLINE int read(){
    if(ied-ibg<=15){unsigned len=ied-ibg;
        memmove(ibuf,ibg,len);
        cin.read((ibg=ibuf)+len,BUFSIZE-len);
    }
    unsigned a=0;char c=*ibg++;bool f=1;
    while(c<'0'||c>'9'){
        if(c=='-')f=0;
        //if(c==0)break;
        c=*ibg++;
    }
    while(c>='0'&&c<='9'){
        a=(a<<1)+(a<<3)+(c^48);
        c=*ibg++;//cerr<<c<<' ';
    }

    return f?a:(~(a-1));
}
constexpr unsigned lg10[15]={1,10,100,1000,10000,100000,1000000,
            10000000,100000000,1000000000};
INLINE void write(unsigned a){
    if((int)(a)<0){
        put('-');
        a=(~(a-1));
    }
    if(a==0){
        put('0');put('\n');return;
    }
    const unsigned *p=upper_bound(lg10,lg10+10,a)-1;
    for(;p>=lg10;p--){
        put(a/(*p)+'0');a%=(*p);
    }
    put('\n');
}
//#define int long long
signed main(){
    //......
    write(1,obuf,obg-obuf);
    return 0;
}

LCA

倍增法:

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+111;
int dep[N];
int net[N][37];
vector<int>g[N];
void dfs(int u,int dad){
    dep[u]=dep[dad]+1;
    net[u][0]=dad;
    for(int i=1;i<=27;i++){
        net[u][i]=net[net[u][i-1]][i-1];
    }
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==dad){
            continue;
        }
        dfs(v,u);
    }
}
int lca(int x,int y){
    if(dep[x]<dep[y]){
        swap(x,y);
    }
    for(int i=27;i>=0;i--){
        if(dep[net[x][i]]>=dep[y]){
            x=net[x][i];
        }
        if(x==y){
            return x;
        }
    }
    for(int i=27;i>=0;i--){
        if(net[x][i]!=net[y][i]){
            x=net[x][i];
            y=net[y][i];
        }
    }
    return net[x][0];
}
int main(){
    int n,m,begi;
    scanf("%d",&n);
    scanf("%d%d",&m,&begi);
    int x,y;
    for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs(begi,0);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    } 
    return 0;
}

树剖法

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6;
int n,m,begi;
int a[N],b[N];
vector<int>g[N];
int tp[N],son[N],dfn[N];
int siz[N],dep[N],fa[N];
int tot;
void dfs1(int u,int dad){
    dep[u]=dep[dad]+1;
    siz[u]=1;
    fa[u]=dad;
    int maxx=-1,maxi=-1;
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==dad){
            continue;
        }
        dfs1(v,u);
        if(siz[v]>maxx){
            maxi=v;
            maxx=siz[v];
        }
        siz[u]+=siz[v];
    }
    son[u]=maxi;
}
void dfs2(int u,int dad,int top){
    dfn[u]=++tot;
    tp[u]=top;
    if(son[u]!=-1){
        dfs2(son[u],u,top);
    }
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==dad||v==son[u]){
            continue;
        }
        dfs2(v,u,v);
    }
}
int lca(int x,int y){
    while(tp[x]!=tp[y]){
        if(dep[tp[x]]<dep[tp[y]]){
            swap(x,y);
        }
        x=fa[tp[x]];
    }
    if(dep[x]>dep[y]){
        swap(x,y);
    }
    return x;
}
signed main(){
    scanf("%lld%lld%lld",&n,&m,&begi);
    for(int i=1;i<n;i++){
        int x,y;
        scanf("%lld%lld",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs1(begi,0);
    dfs2(begi,0,begi);
    while(m--){
        int x,y;
        scanf("%lld%lld",&x,&y);
        printf("%lld\n",lca(x,y));
    }
    return 0;
}

线段树:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6;
int n,m;
struct tree{
    struct pai{
        long long thi,tag;
    };
    pai t[N];
    int _merge(int a,int b){
        return a+b;
    }
    pai merge(pai a,pai b){
        pai ret{_merge(a.thi,b.thi),0};
        return ret;
    }
    void push_down(int k,int cl,int cr){
        if(t[k].tag==0){
            return;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        t[lc].tag+=t[k].tag;
        t[rc].tag+=t[k].tag;
        t[lc].thi+=(mid-cl+1)*t[k].tag;
        t[rc].thi+=(cr-mid)*t[k].tag;
        t[k].tag=0;
    }
    void build(int a[],int k,int cl,int cr){
        if(cl==cr){
            t[k].thi=a[cl];
            return;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        build(a,lc,cl,mid);
        build(a,rc,mid+1,cr);
        t[k]=merge(t[lc],t[rc]);
    }
    void init(int a[]){
        build(a,1,1,n);
    }
    long long qry(int k,int l,int r,int cl,int cr){
        if(cl>r||cr<l||l>r){
            return 0;
        }
        if(cl>=l&&cr<=r){
            return t[k].thi;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        return _merge(qry(lc,l,r,cl,mid),qry(rc,l,r,mid+1,cr));
    }
    void modify(int k,int l,int r,int cl,int cr,long long x){
        if(cl>r||cr<l||l>r){
            return;
        }
        if(l<=cl&&r>=cr){
            t[k].tag+=x;
            t[k].thi+=x*(cr-cl+1);
            return;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        modify(lc,l,r,cl,mid,x);
        modify(rc,l,r,mid+1,cr,x);
        t[k]=merge(t[lc],t[rc]);
    }
}tr;
int a[N];
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    tr.init(a);
    for(int i=1;i<=m;i++){
        int k;
        scanf("%lld",&k);
        if(k==1){
            int x,y,z;
            scanf("%lld%lld%lld",&x,&y,&z);
            tr.modify(1,x,y,1,n,z);
        }else{
            int x,y;
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",tr.qry(1,x,y,1,n));
        }
    }
    return 0;
}

树状数组:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+101;
long long a[N];
int n,m;
struct trma{
    long long tree[N<<1];
    int lowbit(int x){
        return x&(-x);
    }
    void add(int x,int y){
        for(int i=x;i<=n;i+=lowbit(i)){
            tree[i]+=y;
        }
    }
    long long sum(int x){
        long long sum=0;
        for(int i=x;i!=0;i-=lowbit(i)){
            sum+=tree[i];
        }
        return sum;
    }
}tr;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        tr.add(i,a[i]-a[i-1]);
    }
    for(int i=1;i<=m;i++){
        int k;
        scanf("%d",&k);
        if(k==1){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            tr.add(x,z);
            tr.add(y+1,-z);
        }else{
            int x;
            scanf("%d",&x);
            printf("%lld\n",tr.sum(x));
        }
    }
    return 0;
}

ST表:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[200001];
int loge[200001],st[200001][31];
void init(){
    for(int i=2;i<=n;i++){
        loge[i]=loge[i>>1]+1;
    }
    for(int i=1;i<=n;i++){
        st[i][0]=a[i];
    }
    for(int i=1;(1<<i)<=n;i++){
        for(int j=1;j<=n-(1<<i)+1;j++){
            st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]);
        }
    }
}
int find(int x,int y){
    int l=loge[y-x+1];
    return min(st[x][l],st[y-(1<<l)+1][l]);
}
signed main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    init();
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d ",find(x,y));
    }
    return 0;
}

动态开点线段树:

#include<bits/stdc++.h>
using namespace std;
const int N=6.4e6+111;
int mod;
struct pai{
    int thi,tag,lef,rig;
};
int n,m;
struct tree{
    pai t[N];
    int tot;
    void in_it(int x){
        t[x]={0,0,0,0};
    }
    void _init(){
        tot=1;
        in_it(1);
    }
    int _merge(int a,int b){
        return (a+b)%mod;
    }
    pai merge(pai a,pai b,pai c){
        pai ret{_merge(a.thi,b.thi),0,c.lef,c.rig};
        return ret;
    }
    void push_down(int k,int cl,int cr){
        if(t[k].tag==0){
            return;
        }
        if(t[k].lef==0){
            t[k].lef=++tot;
            in_it(t[k].lef);
        }
        if(t[k].rig==0){
            t[k].rig=++tot;
            in_it(t[k].rig);
        }
        int lc=t[k].lef,rc=t[k].rig;
        int mid=(cl+cr)>>1;
        (t[lc].tag+=t[k].tag)%=mod;
        (t[rc].tag+=t[k].tag)%=mod;
        (t[lc].thi+=(mid-cl+1)%mod*1ll*t[k].tag%mod)%=mod;
        (t[rc].thi+=(cr-mid)%mod*1ll*t[k].tag%mod)%=mod;
        t[k].tag=0;
    }
    int qry(int k,int l,int r,int cl,int cr){
        if(k==0){
            return 0;
        } 
        if(cl>=l&&cr<=r){
            return t[k].thi%mod;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        int lc=t[k].lef,rc=t[k].rig;
        int ansl=0,ansr=0;
        if(mid>=l){
            ansl=qry(lc,l,r,cl,mid)%mod;
        }
        if(mid+1<=r){
            ansr=qry(rc,l,r,mid+1,cr)%mod;
        }
        return _merge(ansl,ansr);
    }
    void modify(int& k,int l,int r,int cl,int cr,int x){
//      printf("|%d %d %d %d %d %d\n",k,l,r,cl,cr,x);
        if(k==0){
            k=++tot;
            in_it(k);
        }
        if(l<=cl&&r>=cr){
            (t[k].tag+=x%mod)%=mod;
            (t[k].thi+=x%mod*1ll*(cr-cl+1)%mod)%=mod;
            return;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        if(mid>=l){
            modify(t[k].lef,l,r,cl,mid,x);
        }
        if(mid+1<=r){
            modify(t[k].rig,l,r,mid+1,cr,x);
        }
        t[k]=merge(t[t[k].lef],t[t[k].rig],t[k]);
    }
}tr;
signed main(){
    scanf("%d%d",&m,&mod);
    tr._init();
    for(int i=1;i<=m;i++){
        int k;
        scanf("%d",&k);
        if(k==1){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            int kl=1;
            tr.modify(kl,x,y,1,1000000000,z);
        }else{
            int x,y;
            scanf("%d%d",&x,&y);
            int kl=1;
            printf("%d\n",tr.qry(kl,x,y,1,1000000000));
        }
    }
    return 0;
}

可持久化线段树:

#include<bits/stdc++.h>
using namespace std;
const int N=2.3e7+111;
int n,m;
int a[N];
struct tr{
    struct tree{
        int l,r,u,x;
    }tr[N];
    int tot=0,ver[N];
    void merge(int u){
        tr[u].x=tr[tr[u].l].x+tr[tr[u].r].x;
    }
    int add(int u){
        tr[++tot]=tr[u];
        return tot;
    }
    int build(int u,int l,int r){
        u=++tot;
        if(l==r){
            tr[u].x=a[l];
            return u;
        }
        int mid=(l+r)/2;
        tr[u].l=build(tr[u].l,l,mid);
        tr[u].r=build(tr[u].r,mid+1,r);
        merge(u);
        return u;
    }
    int adtree(int u,int l,int r,int x,int y){
        u=add(u);
        if(l==r){
            tr[u].x=y;
            return u;
        }
        int mid=(l+r)/2;
        if(x<=mid){
            tr[u].l=adtree(tr[u].l,l,mid,x,y);
        }else{
            tr[u].r=adtree(tr[u].r,mid+1,r,x,y);
        }
        merge(u);
        return u;
    }
    int qry(int u,int l,int r,int cl,int cr){
        if(cl>=l&&cr<=r){
            // cerr<<l<<" "<<r<<" "<<tr[u].x<<"\n";
            return tr[u].x;
        }
        int mid=(cl+cr)/2;
        int ans=0;
        if(mid>=l){
            ans+=qry(tr[u].l,l,r,cl,mid);
        }
        if(mid+1<=r){
            ans+=qry(tr[u].r,l,r,mid+1,cr);
        }
        return ans;
    }
}b;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    b.ver[0]=b.build(0,1,n);
    for(int i=1;i<=m;i++){
        int x,op;
        scanf("%d%d",&x,&op);
        if(op==1){
            int y,z;
            scanf("%d%d",&y,&z);
            b.ver[i]=b.adtree(b.ver[x],1,n,y,z);
        }else{
            int y;
            scanf("%d",&y);
            printf("%d\n",b.qry(b.ver[x],y,y,1,n));
            b.ver[i]=b.ver[x];
        }
    }
    return 0;
} 

平衡树(权值线段树模拟)

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e7+111;
struct pai{
    int thi,tag,lef,rig;
};
long long n,m;
struct tree{
    pai t[N];
    int tot;
    void in_it(int x){
        t[x]={0,0,0,0};
    }
    void _init(){
        tot=1;
        in_it(1);
    }
    int _merge(int a,int b){
        return a+b;
    }
    pai merge(pai a,pai b,pai c){
        pai ret{_merge(a.thi,b.thi),0,c.lef,c.rig};
        return ret;
    }
    void push_down(int k,long long cl,long long cr){
        if(t[k].tag==0){
            return;
        }
        if(t[k].lef==0){
            t[k].lef=++tot;
            in_it(t[k].lef);
        }
        if(t[k].rig==0){
            t[k].rig=++tot;
            in_it(t[k].rig);
        }
        int lc=t[k].lef,rc=t[k].rig;
        long long mid=(cl+cr)>>1;
        t[lc].tag+=t[k].tag;
        t[rc].tag+=t[k].tag;
        t[lc].thi+=(mid-cl+1)*1ll*t[k].tag;
        t[rc].thi+=(cr-mid)*1ll*t[k].tag;
        t[k].tag=0;
    }
    int qry(int k,long long l,long long r,long long cl,long long cr){
        if(k==0){
            return 0;
        } 
        if(cl>=l&&cr<=r){
            return t[k].thi;
        }
        long long mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        int lc=t[k].lef,rc=t[k].rig;
        int ansl=0,ansr=0;
        if(mid>=l){
            ansl=qry(lc,l,r,cl,mid);
        }
        if(mid+1<=r){
            ansr=qry(rc,l,r,mid+1,cr);
        }
        return _merge(ansl,ansr);
    }
    int qry2(int k,long long cl,long long cr,int x){
        if(k==0){
            return 0;
        } 
        if(cl==cr){
            return cl;
        }
        long long mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        int lc=t[k].lef,rc=t[k].rig;
        // cerr<<t[lc].thi<<" "<<t[rc].thi<<"|"<<x<<"|"<<lc<<" "<<rc<<"|"<<cl<<" "<<cr<<"\n";
        if(lc!=0&&t[lc].thi>=x){
            return qry2(lc,cl,mid,x);
        }else{
            x-=t[lc].thi;
            return qry2(rc,mid+1,cr,x);
        }
    }
    void modify(int& k,long long l,long long r,long long cl,long long cr,int x){
        if(k==0){
            k=++tot;
            in_it(k);
        }
        if(l<=cl&&r>=cr){
            t[k].tag+=x;
            t[k].thi+=x*1ll*(cr-cl+1);
            return;
        }
        long long mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        if(mid>=l){
            modify(t[k].lef,l,r,cl,mid,x);
        }
        if(mid+1<=r){
            modify(t[k].rig,l,r,mid+1,cr,x);
        }
        t[k]=merge(t[t[k].lef],t[t[k].rig],t[k]);
    }
}tr;
int a[N];
signed main(){
    n=3e7;
    scanf("%lld",&m);
    int k;
    tr._init();
    for(int i=1;i<=m;i++){
        k=1;
        int op,x;
        scanf("%lld%lld",&op,&x);
        if(op!=4){
            x+=1e7+1;
        }
        if(op==1){
            tr.modify(k,x,x,1,n,1);
        }
        if(op==2){
            tr.modify(k,x,x,1,n,-1);
        }
        if(op==3){
            printf("%lld\n",tr.qry(1,1,x-1,1,n)+1);
        }
        if(op==4){
            printf("%lld\n",(int)(tr.qry2(1,1,n,x)-1e7-1));
        }
        if(op==5){
            int y=tr.qry(1,1,x-1,1,n);
            printf("%lld\n",(int)(tr.qry2(1,1,n,y)-1e7-1));
        }
        if(op==6){
            int y=tr.qry(1,1,x,1,n);
            printf("%lld\n",(int)(tr.qry2(1,1,n,y+1)-1e7-1));
        }
    }
    return 0;
}

并查集:

struct disjoint_set{
    int fa[N];
    void _init(){
        for(int i=0;i<=N-11;i++){
            fa[i]=i;
        }
    }
    int find(int x){
        if(fa[x]!=x){
            fa[x]=find(fa[x]);
        }
        return fa[x];
    }
    bool make(int x,int y){
        int fx=find(x);
        int fy=find(y);
        if(fx==fy){
            return 0;
        }
        fa[fx]=fy;
        return 1;
    }
};

线段树合并:

#include<bits/stdc++.h>
using namespace std;
const int N=6.4e6+111;
struct pai{
    int thi,tag,lef,rig;
};
int n,m;
int a[N],a_[N];
struct tree{
    pai t[N];
    int tot=0,grd=0;
    int ver[N];
    void in_it(int x){
        t[x]={0,0,0,0};
    }
    void _init(int grd){
        tot++;
        ver[grd]=tot;
        in_it(tot);
    }
    int _merge(int a,int b){
        return a+b;
    }
    pai merge(pai a,pai b,pai c){
        pai ret{_merge(a.thi,b.thi),0,c.lef,c.rig};
        return ret;
    }
    void push_down(int k,int cl,int cr){
        if(t[k].tag==0){
            return;
        }
        if(t[k].lef==0){
            t[k].lef=++tot;
            in_it(t[k].lef);
        }
        if(t[k].rig==0){
            t[k].rig=++tot;
            in_it(t[k].rig);
        }
        int lc=t[k].lef,rc=t[k].rig;
        int mid=(cl+cr)>>1;
        t[lc].tag=t[k].tag;
        t[rc].tag=t[k].tag;
        t[lc].thi=t[k].tag*(mid-cl+1);
        t[rc].thi=t[k].tag*(cr-mid);
        t[k].tag=0;
    }
    int _make(int ka,int kb,int l,int r){
        if(ka==0&&kb==0){
            return 0;
        }
        if(ka==0){
//          printf("|kb|id=%d l=%d r=%d thi=%d\n",kb,l,r,t[kb].thi); 
            return kb;
        }
        if(kb==0){
//          printf("|ka|id=%d l=%d r=%d thi=%d\n",ka,l,r,t[ka].thi); 
            return ka;
        }
        if(l==r){
//          printf("|kab|id=[%d,%d] l=%d r=%d|ll=%d rr=%d\n",ka,kb,l,r,t[ka].thi,t[kb].thi);
            t[ka].thi=_merge(t[ka].thi,t[kb].thi);
            return ka;
        }
        push_down(ka,l,r);
        push_down(kb,l,r); 
        int mid=(l+r)/2;
        t[ka].lef=_make(t[ka].lef,t[kb].lef,l,mid);
        t[ka].rig=_make(t[ka].rig,t[kb].rig,mid+1,r);
        t[ka]=merge(t[t[ka].lef],t[t[ka].rig],t[ka]);
//        printf("|%d|%d %d|l=%d r=%d thi=%d\n",ka,l,r,t[ka].lef,t[ka].rig,t[ka].thi);
        return ka;
    }
    void make(int &ka,int kb,int l,int r){
        ka=_make(ka,kb,l,r);
    }
    int qry(int k,int l,int r,int cl,int cr){
        if(k==0){
            return 0;
        } 
        if(cl>=l&&cr<=r){
            return t[k].thi;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        int lc=t[k].lef,rc=t[k].rig;
        int ansl=0,ansr=0;
        if(mid>=l){
            ansl=qry(lc,l,r,cl,mid);
        }
        if(mid+1<=r){
            ansr=qry(rc,l,r,mid+1,cr);
        }
        return _merge(ansl,ansr);
    }
    int rank(int k,int cl,int cr,int x){
        if(k==0){
            return -1;
        } 
        if(cl==cr){
            return cl;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        int lc=t[k].lef,rc=t[k].rig;
//      printf("||%d|%d %d|l=%d r=%d|ll=%d rr=%d x=%d\n",k,cl,cr,lc,rc,t[lc].thi,t[rc].thi,x);
        if(t[lc].thi>=x){
            return rank(lc,cl,mid,x);
        }else{
            return rank(rc,mid+1,cr,x-t[lc].thi);
        }
    }
    void modify(int& k,int l,int r,int cl,int cr,int x){
        if(k==0){
            k=++tot;
            in_it(k);
        }
        if(l<=cl&&r>=cr){
            t[k].tag=x;
            t[k].thi=x*(cr-cl+1);
            return;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        if(mid>=l){
            modify(t[k].lef,l,r,cl,mid,x);
        }
        if(mid+1<=r){
            modify(t[k].rig,l,r,mid+1,cr,x);
        }
        t[k]=merge(t[t[k].lef],t[t[k].rig],t[k]);
    }
}tr;
struct disjoint_set{
    int fa[N];
    void _init(){
        for(int i=0;i<=N-11;i++){
            fa[i]=i;
        }
    }
    int find(int x){
        if(fa[x]!=x){
            fa[x]=find(fa[x]);
        }
        return fa[x];
    }
    bool make(int x,int y){
        int fx=find(x);
        int fy=find(y);
        if(fx==fy){
            return 0;
        }
        fa[fy]=fx;
        return 1;
    }
}st;
signed main(){
    st._init();
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a_[a[i]]=i;
        tr._init(i);
        tr.modify(tr.ver[i],a[i],a[i],1,n,1);
    }
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        x=st.find(x);
        y=st.find(y);
        if(x==y){
            continue;
        }
        st.make(x,y);
        tr.make(tr.ver[x],tr.ver[y],1,n);
    }
    int k;
    scanf("%d",&k);
    while(k--){
        char op;
        cin>>op;
        if(op=='Q'){
            int x,y;
            scanf("%d%d",&x,&y);
            x=st.find(x);
            int ans=tr.rank(tr.ver[x],1,n,y);
            printf("%d\n",ans==-1?ans:a_[ans]);
        }else{
            int x,y;
            scanf("%d%d",&x,&y);
            x=st.find(x);
            y=st.find(y);
            if(x==y){
                continue;
            }
            st.make(x,y);
            tr.make(tr.ver[x],tr.ver[y],1,n);
        }
    }
    return 0;
}

线段树分裂

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=6.4e6+111;
struct pai{
    int thi,tag,lef,rig;
};
int n,m;
int a[N];
struct tree{
    pai t[N];
    int tot=0,grd=0;
    int ver[N];
    void in_it(int x){
        t[x]={0,0,0,0};
    }
    void _init(int grd){
        tot++;
        ver[grd]=tot;
        in_it(tot);
    }
    int _merge(int a,int b){
        return a+b;
    }
    pai merge(pai a,pai b,pai c){
        pai ret{_merge(a.thi,b.thi),0,c.lef,c.rig};
        return ret;
    }
    void push_down(int k,int cl,int cr){
        if(t[k].tag==0){
            return;
        }
        if(t[k].lef==0){
            t[k].lef=++tot;
            in_it(t[k].lef);
        }
        if(t[k].rig==0){
            t[k].rig=++tot;
            in_it(t[k].rig);
        }
        int lc=t[k].lef,rc=t[k].rig;
        int mid=(cl+cr)>>1;
        t[lc].tag+=t[k].tag;
        t[rc].tag+=t[k].tag;
        t[lc].thi+=t[k].tag*(mid-cl+1);
        t[rc].thi+=t[k].tag*(cr-mid);
        t[k].tag=0;
    }
    void kill(int &k,int &tp,int l,int r,int cl,int cr){
        if(cr<l||cl>r||k==0){
            return;
        } 
        if(cl>=l&&cr<=r){
            tp=k;
            k=0;
            return;
        }
        if(tp==0){
            tp=++tot;
            in_it(tp);
        }
        int mid=(cl+cr)>>1;
        int lc=t[k].lef,rc=t[k].rig;
        int ltc=t[tp].lef,rtc=t[tp].rig;
        if(mid>=l){
            kill(t[k].lef,t[tp].lef,l,r,cl,mid);
        }
        if(mid+1<=r){
            kill(t[k].rig,t[tp].rig,l,r,mid+1,cr);
        }
        t[k]=merge(t[t[k].lef],t[t[k].rig],t[k]);
        t[tp]=merge(t[t[tp].lef],t[t[tp].rig],t[tp]);
    }
    int make(int ka,int kb,int l,int r){
        if(ka==0&&kb==0){
            return 0;
        }
        if(ka==0){
//          printf("|kb|id=%lld l=%lld r=%lld thi=%lld\n",kb,l,r,t[kb].thi); 
            return kb;
        }
        if(kb==0){
//          printf("|ka|id=%lld l=%lld r=%lld thi=%lld\n",ka,l,r,t[ka].thi); 
            return ka;
        }
        if(l==r){
//          printf("|kab|id=[%lld,%lld] l=%lld r=%lld|ll=%lld rr=%lld\n",ka,kb,l,r,t[ka].thi,t[kb].thi);
            t[ka].thi=_merge(t[ka].thi,t[kb].thi);
            return ka;
        }
        push_down(ka,l,r);
        push_down(kb,l,r); 
        int mid=(l+r)/2;
        t[ka].lef=make(t[ka].lef,t[kb].lef,l,mid);
        t[ka].rig=make(t[ka].rig,t[kb].rig,mid+1,r);
        t[ka]=merge(t[t[ka].lef],t[t[ka].rig],t[ka]);
//        printf("|%lld|%lld %lld|l=%lld r=%lld thi=%lld\n",ka,l,r,t[ka].lef,t[ka].rig,t[ka].thi);
        return ka;
    }
    int qry(int k,int l,int r,int cl,int cr){
        if(k==0){
            return 0;
        } 
        if(cl>=l&&cr<=r){
            return t[k].thi;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        int lc=t[k].lef,rc=t[k].rig;
        int ansl=0,ansr=0;
        if(mid>=l){
            ansl=qry(lc,l,r,cl,mid);
        }
        if(mid+1<=r){
            ansr=qry(rc,l,r,mid+1,cr);
        }
        return _merge(ansl,ansr);
    }
    int rank(int k,int cl,int cr,int x){
        if(k==0){
            return -1;
        } 
        if(cl==cr){
            return cl;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        int lc=t[k].lef,rc=t[k].rig;
//      printf("||%lld|%lld %lld|l=%lld r=%lld|ll=%lld rr=%lld x=%lld\n",k,cl,cr,lc,rc,t[lc].thi,t[rc].thi,x);
        if(t[lc].thi>=x){
            return rank(lc,cl,mid,x);
        }else{
            return rank(rc,mid+1,cr,x-t[lc].thi);
        }
    }
    void modify(int& k,int l,int r,int cl,int cr,int x){
        if(k==0){
            k=++tot;
            in_it(k);
        }
        if(l<=cl&&r>=cr){
            t[k].tag+=x;
            t[k].thi+=x*(cr-cl+1);
            return;
        }
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        if(mid>=l){
            modify(t[k].lef,l,r,cl,mid,x);
        }
        if(mid+1<=r){
            modify(t[k].rig,l,r,mid+1,cr,x);
        }
        t[k]=merge(t[t[k].lef],t[t[k].rig],t[k]);
    }
}tr;
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++){
        tr._init(i);
    }
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        tr.modify(tr.ver[1],i,i,1,n,a[i]);
    }
    int top=1;
    while(m--){
        int op;
        scanf("%lld",&op);
        if(op==0){
            int x,y,z;
            scanf("%lld%lld%lld",&x,&y,&z);
            tr.kill(tr.ver[x],tr.ver[++top],y,z,1,n);
        }else if(op==1){
            int x,y;
            scanf("%lld%lld",&x,&y);
            tr.ver[x]=tr.make(tr.ver[x],tr.ver[y],1,n);
        }else if(op==2){
            int x,y,z;
            scanf("%lld%lld%lld",&x,&y,&z);
            tr.modify(tr.ver[x],z,z,1,n,y);
        }else if(op==3){
            int x,y,z;
            scanf("%lld%lld%lld",&x,&y,&z);
            printf("%lld\n",tr.qry(tr.ver[x],y,z,1,n));
        }else if(op==4){
            int x,y;
            scanf("%lld%lld",&x,&y);
            int ans=tr.rank(tr.ver[x],1,n,y);
            printf("%lld\n",ans);
        }
    }
    return 0;
}

多合一快读

#include <cctype>
#include <cstdio>
#include <cstring>
#include <string>
#include <type_traits>
#include <iostream>
#include <iomanip>

#ifdef __SIZEOF_INT128__
using int128_t = __int128;
#endif

class FastReader {
private:
    static const int SIZE = 1 << 16;
    char buf[SIZE], *p = buf, *end = buf;

    inline void refill() {
        if (p == end) {
            p = buf;
            end = buf + fread(buf, 1, SIZE, stdin);
        }
    }

    inline char getChar() {
        refill();
        return *p++;
    }

    inline void ungetChar() {
        if (p > buf) p--;
    }

    // 跳过空白字符
    inline void skipWhitespace() {
        while (true) {
            refill();
            if (p == end) return;
            char c = *p;
            if (c != ' ' && c != '\n' && c != '\r' && c != '\t') break;
            p++;
        }
    }

    // 读取有符号整数
    template<typename T>
    void readSignedInt(T& x) {
        skipWhitespace();

        bool negative = false;
        char ch = getChar();

        if (ch == '-') {
            negative = true;
            ch = getChar();
        } else if (ch == '+') {
            ch = getChar();
        }

        x = 0;
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + (ch - '0');
            ch = getChar();
        }

        if (!(ch >= '0' && ch <= '9')) {
            ungetChar();
        }

        if (negative) x = -x;
    }

    // 读取无符号整数
    template<typename T>
    void readUnsignedInt(T& x) {
        skipWhitespace();

        char ch = getChar();
        x = 0;
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + (ch - '0');
            ch = getChar();
        }

        if (!(ch >= '0' && ch <= '9')) {
            ungetChar();
        }
    }

    // 读取bool类型
    void readBool(bool& x) {
        skipWhitespace();
        char ch = getChar();

        if (ch == '1') {
            x = true;
        } else if (ch == '0') {
            x = false;
        } else if (ch == 't') {
            // 检查"true"
            getChar(); // 跳过 't'
            getChar(); // 跳过 'r'
            getChar(); // 跳过 'u'
            getChar(); // 跳过 'e'
            x = true;
        } else if (ch == 'f') {
            // 检查"false"
            getChar(); // 跳过 'f'
            getChar(); // 跳过 'a'
            getChar(); // 跳过 'l'
            getChar(); // 跳过 's'
            getChar(); // 跳过 'e'
            x = false;
        } else {
            // 其他情况视为false
            x = false;
        }
    }

    // 读取char类型
    void readChar(char& x) {
        skipWhitespace();
        x = getChar();
    }

    // 读取double类型
    void readDouble(double& x) {
        skipWhitespace();

        x = 0.0;
        char ch = getChar();

        bool negative = false;
        if (ch == '-') {
            negative = true;
            ch = getChar();
        } else if (ch == '+') {
            ch = getChar();
        }

        // 整数部分
        while (ch >= '0' && ch <= '9') {
            x = x * 10.0 + (ch - '0');
            ch = getChar();
        }

        // 小数部分
        if (ch == '.') {
            ch = getChar();
            double fraction = 1.0;
            while (ch >= '0' && ch <= '9') {
                fraction *= 0.1;
                x += (ch - '0') * fraction;
                ch = getChar();
            }
        }

        // 科学计数法
        if (ch == 'e' || ch == 'E') {
            ch = getChar();
            int expSign = 1;
            if (ch == '-') {
                expSign = -1;
                ch = getChar();
            } else if (ch == '+') {
                ch = getChar();
            }

            int exponent = 0;
            while (ch >= '0' && ch <= '9') {
                exponent = exponent * 10 + (ch - '0');
                ch = getChar();
            }

            // 计算10的exponent次方
            double pow10 = 1.0;
            while (exponent > 0) {
                pow10 *= 10.0;
                exponent--;
            }
            if (expSign == -1) x /= pow10;
            else x *= pow10;
        }

        if (!(ch >= '0' && ch <= '9') && ch != '.' && ch != 'e' && ch != 'E' && ch != '+' && ch != '-') {
            ungetChar();
        }

        if (negative) x = -x;
    }

    // 读取float类型
    void readFloat(float& x) {
        double tmp;
        readDouble(tmp);
        x = static_cast<float>(tmp);
    }

    // 读取字符串(单词)
    void readStringWord(std::string& s) {
        skipWhitespace();

        s.clear();
        char ch = getChar();

        while (ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t' && ch != EOF) {
            s.push_back(ch);
            ch = getChar();
        }

        if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOF) {
            ungetChar();
        }
    }

    // 读取整行
    void readStringLine(std::string& s) {
        s.clear();
        char ch = getChar();

        while (ch != '\n' && ch != EOF) {
            s.push_back(ch);
            ch = getChar();
        }

        // 处理Windows换行符\r\n
        if (ch == '\r') {
            ch = getChar();
            if (ch != '\n') {
                ungetChar();
            }
        }
    }

    // 读取C风格字符串
    void readCString(char* s) {
        skipWhitespace();

        char ch = getChar();
        int i = 0;

        while (ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t' && ch != EOF) {
            s[i++] = ch;
            ch = getChar();
        }

        s[i] = '\0';

        if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOF) {
            ungetChar();
        }
    }

#ifdef __SIZEOF_INT128__
    // 读取__int128类型
    void readInt128(int128_t& x) {
        skipWhitespace();

        bool negative = false;
        char ch = getChar();

        if (ch == '-') {
            negative = true;
            ch = getChar();
        } else if (ch == '+') {
            ch = getChar();
        }

        x = 0;
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + (ch - '0');
            ch = getChar();
        }

        if (!(ch >= '0' && ch <= '9')) {
            ungetChar();
        }

        if (negative) x = -x;
    }
#endif

public:
    // 统一的读取函数 - 通过简单的重载实现
    FastReader& read(char& x) {
        readChar(x);
        return *this;
    }

    FastReader& read(short& x) {
        readSignedInt(x);
        return *this;
    }

    FastReader& read(int& x) {
        readSignedInt(x);
        return *this;
    }

    FastReader& read(long& x) {
        readSignedInt(x);
        return *this;
    }

    FastReader& read(long long& x) {
        readSignedInt(x);
        return *this;
    }

    FastReader& read(unsigned short& x) {
        readUnsignedInt(x);
        return *this;
    }

    FastReader& read(unsigned int& x) {
        readUnsignedInt(x);
        return *this;
    }

    FastReader& read(unsigned long& x) {
        readUnsignedInt(x);
        return *this;
    }

    FastReader& read(unsigned long long& x) {
        readUnsignedInt(x);
        return *this;
    }

    FastReader& read(bool& x) {
        readBool(x);
        return *this;
    }

    FastReader& read(float& x) {
        readFloat(x);
        return *this;
    }

    FastReader& read(double& x) {
        readDouble(x);
        return *this;
    }

    FastReader& read(std::string& x) {
        readStringWord(x);
        return *this;
    }

    FastReader& read(char* x) {
        readCString(x);
        return *this;
    }

#ifdef __SIZEOF_INT128__
    FastReader& read(int128_t& x) {
        readInt128(x);
        return *this;
    }
#endif

    // 读取整行的辅助类
    class Line {
    public:
        std::string& str;
        explicit Line(std::string& s) : str(s) {}
    };

    FastReader& read(Line line) {
        readStringLine(line.str);
        return *this;
    }

    // 重载>>运算符
    template<typename T>
    FastReader& operator>>(T& x) {
        return read(x);
    }

    FastReader& operator>>(Line line) {
        return read(line);
    }
};

// 全局FastReader实例
FastReader fin;

// 统一的read函数 - 简单直接的实现
template<typename T>
void read(T& x) {
    fin.read(x);
}

template<typename T, typename... Args>
void read(T& first, Args&... args) {
    read(first);
    read(args...);
}

// 读取整行的辅助函数
inline FastReader::Line readline(std::string& str) {
    return FastReader::Line(str);
}

inline std::string readline() {
    std::string str;
    fin.read(readline(str));
    return str;
}

int main() {
    // 测试各种类型
    char c;
    short s;
    int i;
    long long ll;
    double d;
    bool b;
    std::string word;
    std::string line;

    // 使用read函数读取多个参数
    read(c, s, i, ll, d, b);

    // 读取一个单词
    read(word);

    // 读取整行
    line=readline();

    std::cout << "char: " << c << "\n";
    std::cout << "short: " << s << "\n";
    std::cout << "int: " << i << "\n";
    std::cout << "long long: " << ll << "\n";
    std::cout << "double: " << std::fixed << std::setprecision(6) << d << "\n";
    std::cout << "bool: " << std::boolalpha << b << "\n";
    std::cout << "string (word): " << word << "\n";
    std::cout << "string (line): " << line << "\n";

    // 使用>>运算符
    int x, y;
    fin >> x >> y;
    std::cout << "x: " << x << ", y: " << y << "\n";

    // 读取C风格字符串
    char buffer[100];
    fin >> buffer;
    std::cout << "C string: " << buffer << "\n";

    // 测试__int128(如果支持)
    #ifdef __SIZEOF_INT128__
    int128_t sdfgi128;
    fin >> sdfgi128;
    std::cout << "__int128: " << (long long)(sdfgi128 % 1000000000) << "...\n";
    #endif

    return 0;
}

树链剖分

#include<bits/stdc++.h>
using namespace std;
#define int long long
int mod;
const int N=2e5;
int n,m,begi;
int a[N],b[N];
vector<int>g[N];
struct tree{
    struct pai{
        long long thi,tag;
    };
    pai t[N<<2];
    int _merge(int a,int b){
        return (a+b)%mod;
    }
    pai merge(pai a,pai b){
        pai ret{_merge(a.thi,b.thi),0};
        return ret;
    }
    void push_down(int k,int cl,int cr){
        if(t[k].tag==0){
            return;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        (t[lc].tag+=t[k].tag)%=mod;
        (t[rc].tag+=t[k].tag)%=mod;
        (t[lc].thi+=(mid-cl+1)*t[k].tag)%=mod;
        (t[rc].thi+=(cr-mid)*t[k].tag)%=mod;
        t[k].tag=0;
    }
    void build(int a[],int k,int cl,int cr){
        if(cl==cr){
            t[k].thi=a[cl];
            return;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        build(a,lc,cl,mid);
        build(a,rc,mid+1,cr);
        t[k]=merge(t[lc],t[rc]);
    }
    void init(int a[]){
        build(a,1,1,n);
    }
    long long qry(int k,int l,int r,int cl,int cr){
        if(cl>r||cr<l||l>r){
            return 0;
        }
        if(cl>=l&&cr<=r){
            return t[k].thi%mod;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        return _merge(qry(lc,l,r,cl,mid),qry(rc,l,r,mid+1,cr));
    }
    void modify(int k,int l,int r,int cl,int cr,long long x){
        if(cl>r||cr<l||l>r){
            return;
        }
        if(l<=cl&&r>=cr){
            (t[k].tag+=x)%=mod;
            (t[k].thi+=x*1ll*(cr-cl+1)%mod)%=mod;
            return;
        }
        int lc=k<<1,rc=lc+1;
        int mid=(cl+cr)>>1;
        push_down(k,cl,cr);
        modify(lc,l,r,cl,mid,x);
        modify(rc,l,r,mid+1,cr,x);
        t[k]=merge(t[lc],t[rc]);
    }
}tr;
int tp[N],son[N],dfn[N];
int siz[N],dep[N],fa[N];
int tot;
void dfs1(int u,int dad){
    dep[u]=dep[dad]+1;
    siz[u]=1;
    fa[u]=dad;
    int maxx=-1,maxi=-1;
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==dad){
            continue;
        }
        dfs1(v,u);
        if(siz[v]>maxx){
            maxi=v;
            maxx=siz[v];
        }
        siz[u]+=siz[v];
    }
    son[u]=maxi;
}
void dfs2(int u,int dad,int top){
    dfn[u]=++tot;
    tp[u]=top;
    if(son[u]!=-1){
        dfs2(son[u],u,top);
    }
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==dad||v==son[u]){
            continue;
        }
        dfs2(v,u,v);
    }
}
int qrylist(int x,int y){
    int ans=0;
    while(tp[x]!=tp[y]){
        if(dep[tp[x]]<dep[tp[y]]){
            swap(x,y);
        }
        ans+=tr.qry(1,dfn[tp[x]],dfn[x],1,n);
        ans%=mod;
        x=fa[tp[x]];
    }
    if(dfn[x]>dfn[y]){
        swap(x,y);
    }
    ans+=tr.qry(1,dfn[x],dfn[y],1,n);
    ans%=mod;
    return ans;
}
void modilist(int x,int y,int z){
    while(tp[x]!=tp[y]){
        if(dep[tp[x]]<dep[tp[y]]){
            swap(x,y);
        }
        tr.modify(1,dfn[tp[x]],dfn[x],1,n,z%mod);
        x=fa[tp[x]];
    }
    if(dfn[x]>dfn[y]){
        swap(x,y);
    }
    tr.modify(1,dfn[x],dfn[y],1,n,z%mod);
}
int qrytree(int x){
    return tr.qry(1,dfn[x],dfn[x]+siz[x]-1,1,n);
}
void moditree(int x,int y){
    tr.modify(1,dfn[x],dfn[x]+siz[x]-1,1,n,y%mod);
}
signed main(){
    scanf("%lld%lld%lld%lld",&n,&m,&begi,&mod);
    for(int i=1;i<=n;i++){
        scanf("%lld",&b[i]);
    }
    for(int i=1;i<n;i++){
        int x,y;
        scanf("%lld%lld",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs1(begi,0);
    dfs2(begi,0,begi);
    for(int i=1;i<=n;i++){
        a[dfn[i]]=b[i];
    }
    tr.init(a);
    while(m--){
        int op;
        scanf("%lld",&op);
        if(op==1){
            int x,y,z;
            scanf("%lld%lld%lld",&x,&y,&z);
            modilist(x,y,z);
        }else if(op==2){
            int x,y;
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",qrylist(x,y));
        }else if(op==3){
            int x,y;
            scanf("%lld%lld",&x,&y);
            moditree(x,y);
        }else{
            int x;
            scanf("%lld",&x);
            printf("%lld\n",qrytree(x));
        }
    }
    return 0;
}

treap/splay/FHQ-treap大合集

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+111;
int n;
struct Splay{
    #define ll s[0]
    #define rr s[1]
    int root,tot=0;
    struct tree{
        int s[3];
        int thi,fa,siz,t;
    }tr[N];
    bool right(int u){
        return tr[tr[u].fa].rr==u;
    }
    void init(int u,int x,int fa){
        tr[u].thi=x;
        tr[u].fa=fa;
        tr[u].siz=tr[u].t=1;
    }
    void merge(int u){
        tr[u].siz=tr[tr[u].ll].siz+tr[tr[u].rr].siz+tr[u].t;
    }
    void flyup(int u){
        int y=tr[u].fa;
        int w=tr[y].fa;
        bool nokx=right(u);
        bool noky=right(y);
        tr[w].s[noky]=u;
        tr[u].fa=w;
        tr[y].s[nokx]=tr[u].s[nokx^1];
        tr[tr[u].s[nokx^1]].fa=y;
        tr[u].s[nokx^1]=y;
        tr[y].fa=u;
        merge(y);
        merge(u);
    }
    void splay(int u,int to){
        while(tr[u].fa!=to){
            int y=tr[u].fa;
            int w=tr[y].fa;
            if(w!=to){
                if(right(u)!=right(y)){
                    flyup(u);
                }else{
                    flyup(y);
                }
            }
            flyup(u);
        }
        if(to==0){
            root=u;
        }
    }
    void find(int x){
        int u=root;
        if(u==0){
            return;
        }
        while(tr[u].thi!=x&&tr[u].s[tr[u].thi<x]!=0){
            u=tr[u].s[tr[u].thi<x];
        }
        splay(u,0);
    }
    void add(int x){
        int u=root,fa=0;
        while(u!=0&&tr[u].thi!=x){
            fa=u;
            u=tr[u].s[tr[u].thi<x];
        }
        if(u!=0){
            tr[u].t++;
            splay(u,0);
            return;
        }
        u=++tot;
        init(u,x,fa);
        if(fa!=0){
            tr[fa].s[tr[fa].thi<x]=u;
        }
        splay(u,0);
    }
    int prext(int x,bool f){
        find(x);
        int u=root;
        if(f==0&&tr[u].thi<x){
            return u;
        }
        if(f==1&&tr[u].thi>x){
            return u;
        }
        u=tr[u].s[f];
        while(tr[u].s[f^1]!=0){
            u=tr[u].s[f^1];
        }
        splay(u,0);
        return u;
    }
    void del(int x){
        int l=prext(x,0);
        int r=prext(x,1);
        splay(l,0);
        splay(r,l);
        if(tr[tr[r].ll].t>1){
            tr[tr[r].ll].t--;
            splay(tr[r].ll,0);
            return;
        }
        tr[r].ll=0;
        merge(r);
        merge(l);
    }
    int rank(int u){
        add(u);
        find(u);
        int k=tr[tr[root].ll].siz;
        del(u);
        return k;
    }
    int rankth(int th){
        th++;
        int u=root;
        if(tr[u].siz<th){
            return -1;
        }
        while(1){
            if(th>tr[tr[u].ll].siz+tr[u].t){
                th-=tr[tr[u].ll].siz+tr[u].t;
                u=tr[u].rr;
            }else if(th<=tr[tr[u].ll].siz){
                u=tr[u].ll;
            }else{
                splay(u,0);
                return tr[u].thi;
            }
        }
    }
    void _init(){
        add(-0x3f3f3f3f);
        add(0x3f3f3f3f);
    }
    #undef ll
    #undef rr
};
struct treap{
    #define ll s[0]
    #define rr s[1]
    int root=0,tot=0;
    struct tree{
        int s[3];
        int thi,siz,t,pri;
    }tr[N];
    int init(int x){
        tr[tot].ll=tr[++tot].rr=0;
        tr[tot].thi=x;
        tr[tot].siz=tr[tot].t=1;
        tr[tot].pri=rand();
        return tot;
    }
    void merge(int u){
        if(u==0){
            return;
        }
        tr[u].siz=tr[tr[u].ll].siz+tr[tr[u].rr].siz+tr[u].t;
    }
    int zag(int u){
        int v=tr[u].rr;
        tr[u].rr=tr[v].ll;
        tr[v].ll=u;
        merge(u);
        merge(v);
        return v;
    }
    int zig(int u){
        int v=tr[u].ll;
        tr[u].ll=tr[v].rr;
        tr[v].rr=u;
        merge(u);
        merge(v);
        return v;
    }
    int add(int u,int x){
        if(!u){
            return init(x);
        }
        if(tr[u].thi==x){
            tr[u].t++;
        }else if(x<tr[u].thi){
            tr[u].ll=add(tr[u].ll,x);
            if(tr[tr[u].ll].pri>tr[u].pri){
                u=zig(u);
            }
        }else if(x>tr[u].thi){
            tr[u].rr=add(tr[u].rr,x);
            if(tr[tr[u].rr].pri>tr[u].pri){
                u=zag(u);
            }
        }
        merge(u);
        return u;
    }
    int del(int u,int x){
        if(!u){
            return 0;
        }
        if(tr[u].thi==x){
            if(tr[u].t>1){
                tr[u].t--;
            }else{
                if(!tr[u].ll&&!tr[u].rr){
                    return 0;
                }
                if(!tr[u].ll){
                    u=tr[u].rr;
                }else if(!tr[u].rr){
                    u=tr[u].ll;
                }else{
                    if(tr[tr[u].ll].pri>tr[tr[u].rr].pri){
                        u=zig(u);
                        tr[u].rr=del(tr[u].rr,x);
                    }else{
                        u=zag(u);
                        tr[u].ll=del(tr[u].ll,x);
                    }
                }
            }
        }else if(x<tr[u].thi){
            tr[u].ll=del(tr[u].ll,x);
        }else{
            tr[u].rr=del(tr[u].rr,x);
        }
        merge(u);
        return u;
    }
    int rank(int u,int x){
        if(!u){
            return 1;
        }
        if(tr[u].thi==x){
            return tr[tr[u].ll].siz+1;
        }else if(x<tr[u].thi){
            return rank(tr[u].ll,x);
        }else{
            return rank(tr[u].rr,x)+tr[tr[u].ll].siz+tr[u].t;
        }
    }
    int rankth(int u,int k){
        if(!u){
            return -0x3f3f3f3f3f3f3f3f;
        }
        if(k<=tr[tr[u].ll].siz){
            return rankth(tr[u].ll,k);
        }else if(k<=tr[tr[u].ll].siz+tr[u].t){
            return tr[u].thi;
        }else{
            return rankth(tr[u].rr,k-(tr[tr[u].ll].siz+tr[u].t));
        }
    }
    int prext(int u,int x,bool f){
        if(!u){
            return f?0x3f3f3f3f3f3f3f3f:-0x3f3f3f3f3f3f3f3f;
        }
        if(f==0){
            if(x<=tr[u].thi){
                return prext(tr[u].ll,x,f);
            }else{
                return max(prext(tr[u].rr,x,f),tr[u].thi);
            }
        }else{
            if(x>=tr[u].thi){
                return prext(tr[u].rr,x,f);
            }else{
                return min(prext(tr[u].ll,x,f),tr[u].thi);
            }
        }
    }
    void _init(){
        srand(time(0));
        root=add(root,-0x3f3f3f3f3f3f3f3f);
        root=add(root,0x3f3f3f3f3f3f3f3f);
    }
    #undef ll
    #undef rr
};
struct fhq_treap{
    #define ll s[0]
    #define rr s[1]
    int root=0,tot=0;
    struct tree{
        int s[3];
        int thi,siz,t,pri;
    }tr[N];
    int init(int x){
        tot++;
        tr[tot].ll=tr[tot].rr=0;
        tr[tot].thi=x;
        tr[tot].siz=tr[tot].t=1;
        tr[tot].pri=rand();
        return tot;
    }
    void merge(int u){
        if(u==0){
            return;
        }
        tr[u].siz=tr[tr[u].ll].siz+tr[tr[u].rr].siz+tr[u].t;
    }
    pair<int,int> split(int u,int k){
        if(!u){
            return {0,0};
        }
        if(tr[u].thi<k){
            pair<int,int> v=split(tr[u].rr,k);
            tr[u].rr=v.first;
            merge(u);
            return {u,v.second};
        }else{
            pair<int,int> v=split(tr[u].ll,k);
            tr[u].ll=v.second;
            merge(u);
            return {v.first,u};
        }
    }
    int make(int u,int v){
        if(!u||!v){
            return max(u,v);
        }
        if(tr[u].pri<tr[v].pri){
            tr[u].rr=make(tr[u].rr,v);
            merge(u);
            return u;
        }else{
            tr[v].ll=make(u,tr[v].ll);
            merge(v);
            return v;
        }
    }
    void add(int x){
        int u=init(x);
        pair<int,int> v=split(root,x);
        root=make(make(v.first,u),v.second);
    }
    void del(int x){
        pair<int,int> a;
        a=split(root,x);
        pair<int,int> b;
        b=split(a.second,x+1);
        b.first=make(tr[b.first].ll,tr[b.first].rr);
        root=make(a.first,make(b.first,b.second));
    }
    int rank(int u){
        pair<int,int> v=split(root,u);
        int k=tr[v.first].siz+1;
        root=make(v.first,v.second);
        return k;
    }
    int rankth(int u,int x){
        if(x<=tr[tr[u].ll].siz){
            return rankth(tr[u].ll,x);
        }else if(x==tr[tr[u].ll].siz+1){
            return tr[u].thi;
        }else{
            return rankth(tr[u].rr,x-(tr[tr[u].ll].siz+1));
        }
    }
    int prext(int x,bool f){
        if(!f){
            return rankth(root,rank(x)-1);
        }else{
            return rankth(root,rank(x+1));
        }
    }
}t3;
signed main(){
    scanf("%lld",&n);
    while(n--){
        int op,x;
        scanf("%lld%lld",&op,&x);
        if(op==1){
            t3.add(x);
        }else if(op==2){
            t3.del(x);
        }else if(op==3){
            printf("%lld\n",t3.rank(x));
        }else if(op==4){
            printf("%lld\n",t3.rankth(t3.root,x));
        }else if(op==5||op==6){
            printf("%lld\n",t3.prext(x,op-5));
        }
    }
    return 0;
}

神奇小哈希

struct custom_hash{
    static uint64_t splitmix64(uint64_t x){
        x+=0x9e3779b97f4a7c15;
        x=(x^(x>>30))*0xbf58476d1ce4e5b9;
        x=(x^(x>>27))*0x94d049bb133111eb;
        return x^(x>>31);
    }
    size_t operator()(uint64_t x)const{
        static const uint64_t FIXED_RANDOM=chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x+FIXED_RANDOM);
    }
};