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. 软件工程 speedsnail 第二次冲刺10

    20150527 完成任务:蜗牛碰到线后速度方向的调整:已经基本实现多方向的反射: 遇到问题: 问题1 反射角的问题 解决1 利用tan()三角函数 明日任务: 大总结.找到新问题.布置下一次冲刺方案

  2. CocoaPods 创建私有仓库

    这里有个坑首先需要注意,创建私有cocoapods仓库需要两个git仓库,即代码仓库,Specs文件仓库. 一.创建私有库 1.创建自己源码仓库,假设是A.git; 2.对A仓库: git add . ...

  3. 关于解决乱码问题的一点探索之一(涉及utf-8和GBK)

    在使用Visual Studio 2005进行MFC开发的时候,发现自动添加的注释变成了乱码.像这样: // TODO: ÔÚ´ËÌí¼ÓרÓôúÂëºÍ/»òµ÷ÓûùÀà 还有这样: // ...

  4. Linux系统中增加swap空间大小

    在我的树莓派pi3上编译dlib库时,发现由于内存不足导致编译失败.树莓派是1G内存,swap只有50M,因此将swap增加到500M,编译通过.具体设置方法如下: 使用free命令带上m参数,查看s ...

  5. CentOS7安装Consul集群

    1.准备4台服务器 linux1 192.168.56.101 linux2 192.168.56.102 linux3 192.168.56.103 linux4 192.168.56.104 2. ...

  6. 转 maven3常用命令、java项目搭建、web项目搭建详细图解

    转自地址:http://blog.csdn.net/edward0830ly/article/details/8748986 ------------------------------maven3常 ...

  7. 自己编写 Oracle 分页函数

    CREATE OR REPLACE PACKAGE PACK_PAGINATION AS PAGESIZE CONSTANT ; TYPE TYRECORD_EMP IS RECORD( EMPNO ...

  8. sharepoint content type publishing

    1. Create 1 Project Team sites (Site1) on SharePoint(可以用普通site)2. Go to http://<PCName>:8080/_ ...

  9. 后缀树的线性在线构建-Ukkonen算法

    Ukkonen算法是一个非常直观的算法,其思想精妙之处在于不断加字符的过程中,用字符串上的一段区间来表示一条边,并且自动扩展,在需要的时候把边分裂.使用这个算法的好处在于它非常好写,代码很短,并且它是 ...

  10. POJ 3276 Face The Right Way(前缀和优化)

    题意:有长度为N的01串,有一个操作可以选择连续K个数字取反,求最小的操作数和最小的K使得最后变成全1串.(N<=5000) 由于K是不定的,无法高斯消元. 考虑枚举K,求出最小的操作数. 显然 ...