poj3580 序列之王 fhqtreap

fhqtreap的写法 操作其实都差不多哇

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=200050;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int n,m,sum;
struct node{
    node *l,*r;
    int sz,v,rnd,rev,tag,mn;
    void init(int w){sz=1; v=w; rnd=rand(); mn=w;}
    void add(int w){tag+=w; v+=w; mn+=w;}
    void revs(){rev^=1; swap(l,r);}
    void up(){
        sz=1; mn=v;
        if(l) sz+=l->sz,mn=min(mn,l->mn);
        if(r) sz+=r->sz,mn=min(mn,r->mn);
    }
    void dn(){
        if(rev){if(l) l->revs(); if(r) r->revs(); rev=0;}
        if(tag){if(l) l->add(tag); if(r) r->add(tag); tag=0;}
    }
    void split(node*&lw,node*&rw,int k){
        if(!this){lw=0; rw=0; return ;}
        dn();
        int ls=l?l->sz:0;
        if(ls>=k){
            l->split(lw,l,k);
            rw=this;
        }
        else{
            r->split(r,rw,k-ls-1);
            lw=this;
        }
        up();
    }
}tr[M],*rt;
node *merge(node *a,node *b){
    if(!a) return b;
    if(!b) return a;
    if(a->rnd>b->rnd){
        a->dn();
        a->r=merge(a->r,b);
        a->up();
        return a;
    }{
        b->dn();
        b->l=merge(a,b->l);
        b->up();
        return b;
    }
}
int main()
{
    int l,r,w;
    char ch[15];
    n=read();
    for(int i=1;i<=n;i++) w=read(),tr[i].init(w),rt=merge(rt,tr+i);
    sum=n; m=read();
    while(m--){
        scanf("%s",ch);
        if(ch[0]==‘A‘){
            node *p1,*p2,*p3;
            l=read(); r=read(); w=read();
            rt->split(p2,p3,r);
            p2->split(p1,p2,l-1);
            p2->add(w);
            rt=merge(merge(p1,p2),p3);
        }
        else if(ch[0]==‘M‘){
            node *p1,*p2,*p3;
            l=read(); r=read();
            rt->split(p2,p3,r);
            p2->split(p1,p2,l-1);
            printf("%d\n",p2->mn);
            rt=merge(merge(p1,p2),p3);
        }
        else if(ch[0]==‘R‘&&ch[4]==‘R‘){
            node *p1,*p2,*p3;
            l=read(); r=read();
            if(l==r) continue;
            rt->split(p2,p3,r);
            p2->split(p1,p2,l-1);
            p2->revs();
            rt=merge(merge(p1,p2),p3);
        }
        else if(ch[3]==‘O‘){
            node *p1,*p2,*p3,*p4;
            l=read(); r=read(); w=read()%(r-l+1);
            if(l==r) continue;
            rt->split(p2,p4,r);
            p2->split(p1,p2,l-1);
            p2->split(p2,p3,r-w-l+1);
            rt=merge(merge(p1,p3),merge(p2,p4));
        }
        else if(ch[0]==‘I‘){
            node *p1,*p2;
            l=read(); w=read();
            tr[++sum].init(w);
            rt->split(p1,p2,l);
            rt=merge(merge(p1,tr+sum),p2);
        }
        else if(ch[0]==‘D‘){
            node *p1,*p2,*p3;
            l=read();
            rt->split(p2,p3,l);
            p2->split(p1,p2,l-1);
            rt=merge(p1,p3);
        }
    }
    return 0;
}

时间: 2024-12-28 21:24:27

poj3580 序列之王 fhqtreap的相关文章

fhqtreap入门

介绍 fhqtreap为利用分裂和合并来满足平衡树的性质,不需要旋转操作的一种平衡树. 并且利用函数式编程可以极大的简化代码量. 核心操作 (均为按位置分裂合并) struct fhq { int lc, rc, siz, rnd, val; //lc为左子树,rc为右子树,siz为子树大小(位置分裂即按siz分裂),rnd为随机值,val为该节点储存的值 }t[N]; #define lc (t[rt].lc) #define rc (t[rt].rc) //下方用到的宏定义 split(rt

【模板】fhq-treap

一.什么是\(fhq-treap\) \(fhq-treap\):非旋转\(treap\),顾名思义,不用像普通\(treap\)那样繁琐的旋转,只需要通过分裂和合并,就可以实现基本上是所有数据结构能实现的操作,并且短小.精悍,时间复杂度与\(splay\)齐当,算是一个十分易懂且优秀的算法(并不需要提前学习普通\(treap\)) 接下来,我们就来看看\(fhq-treap\)是怎么实现的 二.\(fhq-treap\) 的性质 在这棵平衡树里面,我们保证 左子树节点的权值(在序列中的位置)全

如何理解“字符串是一组由16位组成的不可变的有序序列”

疑惑点: 1.16位 2.不可变 3.有序序列 解惑: 1.16位指的是:字符串每个字符所占用的空间为16bits 比特(2 bytes);这是因为JS采用的是unicode编码,每个字符需要2个字符. 2.不可变指的是: 字符串对象一旦创建出来,便不能被更改.这可能有些难理解,但事实确实如此.你可能会认为s+='1' 只是在 s 后面增加一个元素 1 而已,但事实是: 先将 s 拷贝一份,记为 temp 在 temp 末尾加上'1' 将 s 变量指向 temp,并删去原来的s 这一特性,可以从

BZOJ 3992 【SDOI2015】 序列统计

题目链接:序列统计 我来复习板子了--这道题也是我写的第一发求原根啊? 求原根方法: 从小到大依次枚举原根.设当前枚举的原根为\(x\),模数为\(p\),\(p-1\)的质因数分别为\(p_1,p_2,\dots,p_m\),则只需检验\(x^{\frac{p}{p_i}}\equiv1 \pmod{p}\)是否成立即可.如果成立则\(x\)不是原根. 然后这道题朴素\(dp\)就不讲了.设\(m\)的原根为\(g\),那么把每个数表示成\(g^k\)的形式就可以乘法变加法了,就成为了\(NT

k序列和

二分答案是参数搜索的一个改善.是这样,对于一个问题,如果它的答案具有单调性质(即如果i不可行,那么大于i的解都不可行,而小于i的解有可能可行),进而用二分的方法枚举答案,再判断答案是否可行,直到求到符合条件为止.例如:问题的答案范围是1到w之间的一个整数,求最小解,那么我们设s=1,t=w,之后mid=(s+t)整除2.然后判断当解是mid的时候这个问题能不能解决,如果能解决则和最优解比较,并且范围缩小到s到mid-1之间(因为即使这个范围没有解,那么mid是最小解):如果不能解决问题,则最小解

3、创建数据库、表空间、权限管理、表、约束、序列

一.dos常用命令 右键→标记→选中要复制的内容→右击就可以完成赋值 ↑表示找前面代码 data 查看日志time 查看时间cls 清屏exit 退出regedit 注册表taskmgr 任务管理器compmgmt.msc计算机管理mspaint 画图板 开始 运行 命令 集锦 --------------------------------write----------写字板 notepad--------打开记事本shrpubw--------创建共享文件夹 calc-----------启

数据结构(括号序列,线段树):ZJOI 2007 捉迷藏

[题目描述] Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条走廊的分布使得任意两个屋子都互相可达. 游戏是这样进行的,孩子们负责躲藏,Jiajia负责找,而Wind负责操纵这N个屋子的灯.在起初的时候,所有的灯都没有被打开.每一次,孩子们只会躲 藏在没有开灯的房间中,但是为了增加刺激性,孩子们会要求打开某个房间的电灯或者关闭某个房间的电灯.为了评估某一次

使用RNN解决NLP中序列标注问题的通用优化思路

/* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 序列标注问题应该说是自然语言处理中最常见的问题,而且很可能是最而没有之一.在深度学习没有广泛渗透到各个应用领域之前,传统的最常用的解决序列标注问题的方案是最大熵.CRF等模型,尤其是CRF,基本是最主流的方法.随着深度学习的不断探索和发展,很可能RNN模型会取代CRF的传统霸主地位,会成为解决序列标注问题的标配解决方案. 本文主要抽象出利用RNN解决序列标注问题的通用优化思路.这个RNN优化思路应该

BZOJ 1251 序列终结者(Splay)

题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思.这道题目 就叫序列终结者吧.[问题描述] 给定一个长度为N的序列,每个序列的元素是一个整数(废话).要支持以下三种操作: 1. 将 [L, R] 这个区间内的所有数加上 V. 2. 将 [