初学写fhqtreap样例过了,但全wa求助!

P3391 【模板】文艺平衡树

Xiongzx @ 2023-03-15 21:57:11

#include <bits/stdc++.h>

#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define pre(i, a, b) for(int i = (a); i >= (b); i--)
#define Ede(i, u) for(int i = h[u]; i; i = ne[i])
#define go(i, a) for(auto i : a)
//#define int long long
#define LL long long
#define ULL unsigned long long
#define PII pair<int, int>
#define PIL pair<int, long long>
#define PLI pair<long long, int>
#define PLL pair<long long, long long>
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define sf scanf
#define prf printf
#define el putchar('\n')
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define mmc(arr1, arr2) memcpy(arr1, arr2, sizeof(arr2))
const int inf = 0x3f3f3f3f;

template <typename T> inline void rd(T &x){
    x = 0; bool f = true; char ch = getchar();
    while(ch < '0' || ch > '9'){ f = ((ch == '-') ? false : true); ch = getchar();}
    while(ch >= '0' && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar();}
    if(!f) x = -x;
}
template <typename T, typename ...Args> inline void rd(T &x, Args &...args){ rd(x); rd(args...);}

using namespace std;

const int N = 1e6 + 10;
struct node{
    int l, r;
    int val, key, siz;
    int tag;
}tr[N];
int n, m, root, idx;

int newnode(int v){
    tr[++idx].val = v;
    tr[idx].key = rand();
    tr[idx].siz = 1;
    return idx;
}
void pushup(int p){
    tr[p].siz = tr[tr[p].l].siz + tr[tr[p].r].siz + 1;
}
void pushdown(int p){
    if(!tr[p].tag) return;
    swap(tr[p].l, tr[p].r);
    tr[tr[p].l].tag ^= 1, tr[tr[p].r].tag ^= 1;
    tr[p].tag = 0; 
}
void split(int p, int k/*排名*/, int &x, int &y){
    if(!p){
        x = y = 0;
        return;
    }
    pushdown(p);
    if(k >= (tr[tr[p].l].siz + 1)){
        x = p;
        split(tr[p].r, k - (tr[tr[p].l].siz + 1), tr[p].r, y); 
    }
    else{
        y = p;
        split(tr[p].l, k, x, tr[p].l);  
    }
    pushup(p);
}
int merge(int x, int y){
    if(!x || !y) return x + y;
    if(tr[x].key < tr[y].key){
        pushdown(x);
        tr[x].r = merge(tr[x].r, y); pushup(x); return x;
    }
    else{
        pushdown(y);
        tr[y].l = merge(x, tr[y].l); pushup(y); return y;
    }
}
void print(int p){ //中序遍历 
    if(!p) return;
    pushdown(p);
    print(tr[p].l);
    prf("%d ", tr[p].val);
    print(tr[p].r);
}
int main(){
    /*
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
    */
    rd(n, m);
    rep(i, 1, n) root = merge(root, newnode(i)); 
    rep(i, 1, m){
        int l, r; rd(l, r);
        int x, y, z;
        split(root, l - 1, x, y);
        split(y, r, y, z);
        tr[y].tag ^= 1;
        root = merge(merge(x, y), z);
    }
    print(root);
    return 0;
}

by ly_father @ 2023-04-20 08:16:08

第二次分裂的应该是split(y, r - l + 1, y, z) 然后合并的顺序不能交换你写root = merge(merge(x, y), z)肯定不对,应该按照分裂的顺序去和合并root = merge(x, merge(y, z))我改过给你交了一发可以AC,你可以照着上述我提出的错误去改一下


|