作业(?)

我写了几颗fhq treap, 用它们解决了洛谷上的三个模板题 : 普通平衡树、 文艺平衡树、 线段树1.


//普通平衡树
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int tot,ls[maxn],rs[maxn],val[maxn],rnd[maxn],siz[maxn];
int rt;
int newnode(int weight)
{
    val[++tot]=weight;
    rnd[tot]=rand();
    siz[tot]=1;
    return tot;
}
void update(int k)
{
    siz[k] = 1 + siz[ls[k]] + siz[rs[k]];
}

void merge(int &k,int a,int b)
{
    if(!a||!b) {
        k=a+b;
        return;
    }
    if(rnd[a] < rnd[b])
    {
        k=a;
        merge(rs[a], rs[a], b);
    }
    else
    {
        k=b;
        merge(ls[b], a, ls[b]);
    }
    update(k);
}

void split(int k,int &a,int &b,int weight)
{
    if(!k)
    {
        a=b=0;
        return;
    }
    if(val[k] <= weight)
    {
        a=k;
        split(rs[a], rs[a], b, weight);
    }
    else
    {
        b=k;
        split(ls[b], a, ls[b], weight);
    }
    update(k);
}

int kth(int k)
{
    int p=rt;
    while(1)
    {
        if(siz[ls[p]] + 1 == k) return val[p];
        else
        if(siz[ls[p]] + 1 < k) k-=siz[ls[p]]+1, p=rs[p];
        else
        p=ls[p];
    }
}

int mx(int p)
{
    while(rs[p]) p=rs[p];
    return val[p];
}

int mi(int p)
{
    while(ls[p]) p=ls[p];
    return val[p];
}

int main()
{
    srand((unsigned)time(0));
    int n; cin >> n;
    while(n--)
    {
        int opt,x; scanf("%d%d",&opt,&x);
        if(opt==1)
        {
            int a=0,b=0,nnode=newnode(x);
            split(rt,a,b,x);
            merge(a,a,nnode);
            merge(rt,a,b);
        }
        if(opt==2)
        {
            int a=0,b=0,c=0;
            split(rt,b,c,x);
            split(b,a,b,x-1);
            merge(b,ls[b],rs[b]);
            merge(a,a,b);
            merge(rt,a,c);
        }
        if(opt==3)
        {
            int a=0,b=0;
            split(rt,a,b,x-1);
            cout<<siz[a]+1<<'\n';
            merge(rt,a,b);
        }
        if(opt==4)
        {
            cout<<kth(x)<<'\n';
        }
        if(opt==5)
        {
            int a=0,b=0;
            split(rt,a,b,x-1);
            cout<<mx(a)<<'\n';
            merge(rt,a,b);
        }
        if(opt==6)
        {
            int a=0,b=0;
            split(rt,a,b,x);
            cout<<mi(b)<<'\n';
            merge(rt,a,b);
        }
    }
    return 0;
}

//文艺平衡树
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int n,m;

int rnd[maxn],tag[maxn],ls[maxn],rs[maxn],siz[maxn],val[maxn];
int rt;
int newnode(int x)
{
    val[x]=x; siz[x]=1; rnd[x]=rand();
    return x;
}
void update(int k)
{
    siz[k] = 1 + siz[ls[k]] + siz[rs[k]];
}
void pushdown(int k)
{
    swap(ls[k], rs[k]);
    tag[k]=0;
    tag[ls[k]] ^= 1;
    tag[rs[k]] ^= 1;
}

void merge(int &k,int a,int b)
{
    if(!a||!b) {
        k=a+b;
        return;
    }
    if(rnd[a]<rnd[b])
    {
        k=a;
        if(tag[a]) pushdown(a);
        merge(rs[a],rs[a],b);
    }
    else
    {
        k=b;
        if(tag[b]) pushdown(b);
        merge(ls[b],a,ls[b]);
    }
    update(k);
}

void split(int k,int &a,int &b,int weight)
{
    if(!k) {
        a=b=0;
        return;
    }
    if(tag[k]) pushdown(k);
    if(siz[ls[k]] + 1 <= weight)
    {
        a=k;
        split(rs[a],rs[a],b,weight-siz[ls[a]]-1);
    }
    else
    {
        b=k;
        split(ls[b],a,ls[b],weight);
    }
    update(k);
}

void mid(int k)
{
    if(!k) return;
    if(tag[k]) pushdown(k);
    mid(ls[k]);
    cout<<val[k]<<' ';
    mid(rs[k]);
}

int main()
{
    srand((unsigned)time(0));
    cin >> n >> m;
    for(int i=1;i<=n;++i)
    {
        int nnode=newnode(i);
        merge(rt,rt,nnode);
    }
    while(m--)
    {
        int l,r; scanf("%d%d",&l,&r);
        int a=0,b=0,c=0;
        split(rt,b,c,r);
        split(b,a,b,l-1);
        tag[b]^=1;
        merge(b,b,c);
        merge(rt,a,b);
    }
    mid(rt);
    return 0;
}

//线段树1
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;

int ls[maxn],rs[maxn],siz[maxn],rnd[maxn];
long long val[maxn],sum[maxn],tag[maxn];
int tot,rt;

int newnode(long long v)
{
    val[++tot]=v; sum[tot]=v; rnd[tot]=rand(); siz[tot]=1; return tot;
}

void update(int k)
{
    siz[k] = siz[ls[k]] + siz[rs[k]] + 1;
    sum[k] = sum[ls[k]] + sum[rs[k]] + val[k];
}

//lazy tag
void ad(int k,long long v)
{
    val[k] += v;
    sum[k] += siz[k] * v;
}
void pushdown(int k)
{
    ad(ls[k], tag[k]); tag[ls[k]] += tag[k];
    ad(rs[k], tag[k]); tag[rs[k]] += tag[k];
    tag[k]=0;
}
//

void merge(int &k,int a,int b)
{
    if(!a||!b) {
        k=a+b;
        return;
    }
    if(rnd[a] < rnd[b])
    {
        k=a;
        if(tag[a]) pushdown(a);
        merge(rs[a], rs[a], b);
    }
    else
    {
        k=b;
        if(tag[b]) pushdown(b);
        merge(ls[b], a, ls[b]);
    }
    update(k);
}

void split(int k,int &a,int &b,int weight)
{
    if(!k) {
        a=b=0;
        return;
    }
    if(tag[k]) pushdown(k);
    if(siz[ls[k]] + 1 <= weight)
    {
        a=k;
        split(rs[a], rs[a], b, weight - siz[ls[a]] - 1);
    }
    else
    {
        b=k;
        split(ls[b], a, ls[b], weight);
    }
    update(k);
}

int main()
{
    int n,m; scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
    {
        long long x; scanf("%lld", &x);
        int nnode=newnode(x);
        merge(rt,rt,nnode);
    }
    while(m--)
    {
        int opt,l,r;
        scanf("%d%d%d",&opt, &l, &r);
        if(opt==1)
        {
            long long k; scanf("%lld",&k);
            int a=0,b=0,c=0;
            split(rt,b,c,r);
            split(b,a,b,l-1);
            ad(b,k); tag[b]+=k;
            merge(a,a,b);
            merge(rt,a,c);
        }
        else
        {
            int a=0,b=0,c=0;
            split(rt,b,c,r);
            split(b,a,b,l-1);
            cout<<sum[b]<<'\n';
            merge(a,a,b);
            merge(rt,a,c);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tztqwq/p/12070177.html