3678: wangxz与OJ

Time Limit: 10 Sec  Memory Limit: 128 MB
http://www.lydsy.com/JudgeOnline/problem.php?id=3678

Description

某天,wangxz神犇来到了一个信息学在线评测系统(Online Judge)。由于他是一位哲♂学的神犇,所以他不打算做题。他发现这些题

目呈线性排列,被标记为1~n号,每道题都有一个难度值(可以<=0)。他决定与这些题目玩♂耍。

1、他可以在某个位置插♂入一些难度值特定的题目。

2、他可以吃♂掉(删除)一段题目。

3、他可以查询某个位置的题目的难度值。

维护一个初始有n个元素的序列(标记为1~n号元素),支持以下操作:

0 p a b (0<=p<=当前序列元素个数) (a<=b) 在p位置和p+1位置之间插入整数:a,a+1,a+2,...,b-1,b。若p为0,插在序列最前面;

1 a b (1<=a<=b<=当前序列元素个数) 删除a,a+1,a+2,...,b-1,b位置的元素;

2 p (1<=p<=当前序列元素个数) 查询p位置的元素。

Input

输入第一行包括两个正整数n(1<=n<=20000),m(1<=m<=20000),代表初始序列元素个数和操作个数。

接下来n个整数,为初始序列元素。

接下来m行,每行第一个为整数sym,

若sym=0,接下来有一个非负整数p,两个整数a,b;

若sym=1,接下来有两个正整数a,b;

若sym=2,接下来有一个正整数p;

p、x、y的含义及范围见题目描述。

在任何情况下,保证序列中的元素总数不超过100000。

保证题目涉及的所有数在int内。

Output

对每个sym=2,输出一行,包括一个整数,代表询问位置的元素。

Sample Input

5 3
1 2 3 4 5
0 2 1 4
1 3 8
2 2

Sample Output

2
 
插入时插一个大节点,使用到他时分裂节点
大节点发现是公差为1的等差数列,所以记录首项、末项即可
#include<cstdio>
#define N 20001
using namespace std;
int n,m,tot,t1,t2,root;
int key[N*][],siz[N*],ch[N*][],fa[N*];
int read()
{
int x=,f=; char c=getchar();
while(c<''||c>'') { if(c=='-') f=-; c=getchar(); }
while(c>=''&&c<='') { x=x*+c-''; c=getchar(); }
return x*f;
}
struct SPLAY_TREE
{
void update(int k)
{
siz[k]=key[k][]-key[k][]+;
if(ch[k][]) siz[k]+=siz[ch[k][]];
if(ch[k][]) siz[k]+=siz[ch[k][]];
}
void build(int l,int r,int f)
{
if(l>r) return;
int mid=l+r>>;
siz[mid]=; fa[mid]=f; ch[f][mid>f]=mid;
build(l,mid-,mid);
build(mid+,r,mid);
update(mid);
}
void rotate(int x,int & goal)
{
int y=fa[x],z=fa[y],k=ch[y][]==x;
if(y==goal) goal=x;
else ch[z][ch[z][]==y]=x;
ch[y][k]=ch[x][k^]; ch[x][k^]=y;
fa[y]=x; fa[ch[y][k]]=y; fa[x]=z;
update(y);
}
bool getson(int x)
{
return ch[fa[x]][]==x;
}
void splay(int x,int & goal)
{
while(x!=goal)
{
int y=fa[x];
if(y!=goal)
{
if(getson(x)==getson(y)) rotate(y,goal);
else rotate(x,goal);
}
rotate(x,goal);
update(x);
}
}
int find(int now,int k)
{
if(k<=siz[ch[now][]]) return find(ch[now][],k);
else if(siz[now]-siz[ch[now][]]<k) return find(ch[now][],k-siz[now]+siz[ch[now][]]);
else
{
k-=siz[ch[now][]];
if(k!=)
{
fa[ch[++tot][]=ch[now][]]=tot; fa[ch[now][]=tot]=now;
key[tot][]=key[now][]; key[tot][]=key[tot][]+k-; key[now][]=key[tot][]+;
update(tot);
k=;
}
if(k!=key[now][]-key[now][]+)
{
fa[ch[++tot][]=ch[now][]]=tot; fa[ch[now][]=tot]=now;
key[tot][]=key[now][]; key[tot][]=key[now][]+k; key[now][]=key[tot][]-;
update(tot);
}
return now;
}
}
void spilt(int l,int r)
{
t1=find(root,l);
t2=find(root,r);
splay(t1,root);
splay(t2,ch[root][]);
}
}Splay;
int main()
{
/*freopen("data.txt","r",stdin);
freopen("my2.txt","w",stdout);*/
n=read(); m=read();
for(int i=;i<=n;i++) key[i+][]=key[i+][]=read();
Splay.build(,n+,);
tot=n+; root=n+>>;
int op,p,a,b;
while(m--)
{
scanf("%d",&op);
if(!op)
{
p=read(); a=read(); b=read();
Splay.spilt(p+,p+);
fa[ch[t2][]=++tot]=t2; key[tot][]=a; key[tot][]=b; siz[tot]=b-a+;
Splay.update(t2); Splay.update(t1);
}
else if(op==)
{
a=read(); b=read();
Splay.spilt(a,b+);
ch[t2][]=;
Splay.update(t2); Splay.update(t1);
}
else
{
p=read();
p=Splay.find(root,p+);
printf("%d\n",key[p][]);
}
}
}

狂WA代码:

#include<cstdio>
#define N 20005
using namespace std;
int n,m,now,tmp,root;
int a[N];
int siz[N*],fa[N*],key[N*],ch[N*][],cnt[N*];
int tot;
struct SPLAY_TREE
{
void update(int k)
{
siz[k]=cnt[k];
if(ch[k][]) siz[k]+=siz[ch[k][]];
if(ch[k][]) siz[k]+=siz[ch[k][]];
}
void build(int l,int r,int f)
{
if(l>r) return;
int mid=l+r>>;
if(mid<f) ch[f][]=mid;
else ch[f][]=mid;
siz[mid]=; cnt[mid]=; fa[mid]=f; key[mid]=a[mid];
build(l,mid-,mid);
build(mid+,r,mid);
update(mid);
}
int find_id(int x)
{
now=root;
while()
{
if(ch[now][]&&siz[ch[now][]]>=x) now=ch[now][];
else
{
tmp=(ch[now][] ? siz[ch[now][]] : )+cnt[now];
if(x<=tmp) return now;
x-=tmp;
now=ch[now][];
}
}
}
int getson(int x)
{
return ch[fa[x]][]==x;
}
void rotate(int x,int & goal)
{
int y=fa[x],z=fa[y],k=ch[y][]==x;
if(y==goal) goal=x;
else ch[z][ch[z][]==y]=x;
ch[y][k]=ch[x][k^]; ch[x][k^]=y;
fa[y]=x; fa[ch[y][k]]=y; fa[x]=z;
update(y);
}
void splay(int x,int & goal)
{
int y;
while(x!=goal)
{
y=fa[x];
if(y!=goal)
{
if(getson(x)==getson(y)) rotate(y,goal);
else rotate(x,goal);
}
rotate(x,goal);
update(x);
}
}
void insert_suf(int s,int t)
{
if(!ch[root][]) now=root;
else
{
now=ch[root][];
while(ch[now][]) now=ch[now][];
}
siz[++tot]=cnt[tot]=t-s+;
key[tot]=(s+t)*(t-s+)/;
fa[tot]=now;
ch[now][]=tot;
splay(tot,root);
}
void insert_pre(int s,int t)
{
if(!ch[root][]) now=root;
else
{
now=ch[root][];
while(ch[now][]) now=ch[now][];
}
siz[++tot]=cnt[tot]=t-s+;
key[tot]=(s+t)*(t-s+)/;
fa[tot]=now;
ch[now][]=tot;
splay(tot,root);
}
int find_pre()
{
now=ch[root][];
while(ch[now][]) now=ch[now][];
return now;
}
int find_suf()
{
now=ch[now][];
while(ch[now][]) now=ch[now][];
return now;
}
void del()
{
if(!ch[root][]&&!ch[root][]) root=;
else if(!ch[root][])
{
tmp=root;
root=ch[root][];
fa[root]=;
ch[tmp][]=;
}
else if(!ch[root][])
{
tmp=root;
root=ch[root][];
fa[root]=;
ch[tmp][]=;
}
else
{
int pre=find_pre();
tmp=root;
splay(pre,root);
ch[root][]=ch[tmp][];
if(ch[root][]) fa[ch[root][]]=root;
update(root);
}
}
}Splay;
int main()
{
/*freopen("data.txt","r",stdin);
freopen("my.txt","w",stdout);*/
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&a[i+]);
Splay.build(,n+,);
root=n+>>;
int op,p,aa,bb,q;
int cutl,cutr;
int shouxiang1,shouxiang2,moxiang1,moxiang2,rest_in_aa,rest_in_bb;
tot=n+;
while(m--)
{
scanf("%d",&op);
if(op==)
{
scanf("%d%d%d",&p,&aa,&bb);
p++;q=p;
p=Splay.find_id(p);
Splay.splay(p,root);
if(cnt[p]==) Splay.insert_suf(aa,bb);
else
{
cutl=q-siz[ch[root][]]-;
cutr=siz[root]-siz[ch[root][]]-q;
shouxiang1=(*key[root]/cnt[root]-cnt[root]+)/;
moxiang1=shouxiang1+cutl-;
shouxiang2=moxiang1+;
moxiang2=shouxiang2+cutr-;
siz[root]=siz[root]-cnt[root]+;
cnt[root]=;
key[root]=moxiang1+;
Splay.insert_pre(shouxiang1,moxiang1);
Splay.splay(p,root);
Splay.insert_suf(shouxiang2,moxiang2);
Splay.splay(p,root);
Splay.insert_suf(aa,bb);
}
}
else if(op==)
{
scanf("%d%d",&aa,&bb);
aa++; bb++;
p=aa; q=bb;
aa=Splay.find_id(aa);
bb=Splay.find_id(bb);
if(aa==bb)
{
Splay.splay(aa,root);
cutl=p-siz[ch[root][]]-;
//cutr=siz[root]-siz[ch[root][1]]-q;
cutr=cnt[root]-cutl-(q-p+);
shouxiang1=(*key[root]/cnt[root]-cnt[root]+)/;
moxiang1=shouxiang1+cutl-;
shouxiang2=moxiang1+q-p+;//+1
moxiang2=shouxiang2+cutr-;
if(shouxiang1<=moxiang1)
{
Splay.insert_pre(shouxiang1,moxiang1);//++
Splay.splay(aa,root);
siz[root]=siz[root]-(moxiang1-shouxiang1+);
cnt[root]=cnt[root]-(moxiang1-shouxiang1+);
key[root]=key[root]-(shouxiang1+moxiang1)*(moxiang1-shouxiang1+)/;
}
siz[root]=siz[root]-(q-p+);
cnt[root]=cnt[root]-(q-p+);
key[root]=key[root]-(shouxiang2-+shouxiang2--(q-p+)+)*(q-p+)/;
if(!cnt[root]) Splay.del();
continue;
}
Splay.splay(aa,root);
rest_in_aa=p-siz[ch[root][]]-;
Splay.splay(bb,ch[root][]);
rest_in_bb=cnt[bb]-(q-p+-(cnt[aa]-rest_in_aa+siz[ch[bb][]]));//+1
siz[aa]-=siz[ch[bb][]];
siz[bb]-=siz[ch[bb][]];
ch[bb][]=;
shouxiang1=(*key[bb]/cnt[bb]-cnt[bb]+)/;
key[bb]-=(shouxiang1+shouxiang1+cnt[bb]-rest_in_bb-)*(cnt[bb]-rest_in_bb)/;
cnt[bb]=rest_in_bb;
Splay.update(bb);
shouxiang1=(*key[aa]/cnt[aa]-cnt[aa]+)/;
key[aa]=(shouxiang1+shouxiang1+rest_in_aa-)*rest_in_aa/;
cnt[aa]=rest_in_aa;
Splay.update(aa);
}
else
{
scanf("%d",&p);
p++;
q=Splay.find_id(p);
if(cnt[q]==) printf("%d\n",key[q]);
else
{
Splay.splay(q,root);
p=p-siz[ch[root][]];
shouxiang1=(*key[root]/cnt[root]-cnt[root]+)/;
printf("%d\n",shouxiang1+p-);
}
}
}
}

bzoj 3678 wangxz与OJ的更多相关文章

  1. 【BZOJ3678】wangxz与OJ Splay

    [BZOJ3678]wangxz与OJ Description 某天,wangxz神犇来到了一个信息学在线评测系统(Online Judge).由于他是一位哲♂学的神犇,所以他不打算做题.他发现这些题 ...

  2. 【bzoj3678】wangxz与OJ

    Portal -- > bzoj 3678 Solution 这题==真实智力康复qwq 然而众多神犇都说是10min写完的题我..可能写了近1h吧==深深感受到自己的弱小qwq (丢上来是因为 ...

  3. BZOJ3678: wangxz与OJ

    splay缩点. #include<bits/stdc++.h> #define L(t) (t)->c[0] #define R(t) (t)->c[1] #define F ...

  4. 【BZOJ3678】Wangxz和OJ

    题意: 不想讲 题解: Rope真香! 正解是Splay缩点,访问时再拆成一个序列 代码: //STL dafa good! #include<algorithm> #include< ...

  5. BZOJ3678 wangxz与OJ (平衡树 无旋treap)

    题面 维护一个序列,支持以下操作: 1.在某个位置插入一段值连续的数. 2.删除在当前序列位置连续的一段数. 3.查询某个位置的数是多少. 题解 显然平衡树,一个点维护一段值连续的数,如果插入或者删除 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. NOIp2018模拟赛三十六

    好久没打模拟赛了...今天一样是两道国集,一道bzoj题 成绩:13+0+95=108 A题开始看错题了...导致样例都没看懂,结果xfz提醒我后我理解了一个我自认为正确的题意(事实证明我和xfz都错 ...

  8. HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT

    一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...

  9. bzoj 4811 由乃的OJ

    bzoj 4811 由乃的OJ 考虑树链剖分. 树剖后用一颗线段树维护一段连续区间,类似于一个函数,各位上进入 \(0/1\) ,输出的数字分别是什么.注意到最多只有 \(64\) 位,可以用一个 \ ...

随机推荐

  1. MathExam第二次作业(升级版)

    MathExamLv2——林华伟 211506319 陈珍 211406263   一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实 ...

  2. 04慕课网《vue.js2.5入门》——Vue-cli开发todolist

    主要文件目录: 文件代码: 根实例,初始化vue: <!--index.html,网站入口页面,和main.jsp组成一套.vue文件,包含--> <!DOCTYPE html> ...

  3. .net web 应用程序C#

    简介 开发环境:VS2015 ASP.NET:可以开发出几乎所有运行在Windows上的应用程序:.NET是一种架构,一种新的API:引入程序集代替DLL: ADO.NET:一组.NET组件提供对数据 ...

  4. Web-JSP表单字符验证

    代码后续补上

  5. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

  6. redis 入手

    redis是数据库,数据库肯定是处理处理数据.既然是处理数据,无非就是增删查改 redis用于操作键的命令基本上分为两大类 对任何键都可执行的: DEL 命令. EXPIRE 命令. RENAME 命 ...

  7. CPU测试--查看cpu占用率

    一.使用命令adb shell top -m 10 -s cpu(-t 显示进程名称,-s 按指定行排序,-n 在退出前刷新几次,-d 刷新间隔,-m 显示最大数量),如下图: 参数含义: PID:p ...

  8. adb使用过程常见的几种错误总结

    问题1:Failure [INSTALL_FAILED_ALREADY_EXISTS] 问题原因:该程序已存在. 解决方法:增加-r参数,即可成功覆盖安装 问题2:Failure [INSTALL_F ...

  9. Vue 自定义指令练习

    Vue.directive(id,definition)注册一个全局自定义指令,接收两个参数,指令ID以及定义对象 取值: <div v-demo="{ color: 'white', ...

  10. 【JavaScript&jQuery】轮展图

    用bootstrap实现轮展图和用Jquery自定义轮展图两种   1.使用bootstrap插件 效果图: 用一个超简单的方法,那就是用bootstrap的插件,什么?不懂bootstrap?没关系 ...