【BZOJ-3337】ORZJRY I 块状链表
3337: ORZJRY I
Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 190  Solved: 50
[Submit][Status][Discuss]
Description
Jry最近做(屠)了很多数据结构题,所以想 BS你,他希望你能实现一种数据结构维护一个序列:

Input
第一行n;
第二行n个数;
第三行q,代表询问个数;
接下来q行,每行一个op,输入格式见描述。
Output
对于7≤op≤11的操作,一行输出一个答案。
Sample Input
5 2 6 3 1 4
15
7 2 4
8 1 3
9 2 4 5
10 1 6 4
11 2 5 4
6 1 4 7
8 1 4
5 3 4 5
2 1
1 2 8
3 3 5
4 1 5 2
9 2 5 4
10 3 6 4
11 1 6 100
Sample Output
4
1
4
3
0
3
12
6
HINT
n,q≤100000;
任意时刻数列中的数≤2^31-1。
0≤任意时刻数列中的数≤2^31-1。
Source
Solution
switch(opt)
		{
			  case 1: 直接分裂后插入即可  break;
			  case 2: 分裂后直接删除  break;
			  case 3: 分裂得到[l,r]将指向l的块指向r,l指向r指向的块,然后给[l,r]中所有块打上反转标记  break;
			  case 4: 提取出[r-k,r],将这段从中删除,再整段插入到l之前  break;
			  case 5: 提取[l,r],打tag标记  break;
			  case 6: 提取[l,r],打del标记  break;
			  case 7: 提取[l,r],扫描一遍区间中的所有块,统计sum  break;
			  case 8: 同上,统计max和min,输出max-min  break;
			  case 9: 二分,找到最接近它的两个,统计答案  break;
			  case 10:二分,用下述方法check  break;
			  case 11: 二分统计个数  break;
		}
上述这些二分大都可以用upper_bound/lower_bound,注意的是Split和Merge的时候要PushDown和Update
千万不要在查询的时候PushDown...那样复杂度会炸!
Code
(本机AC,OJ TLE)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<ctime>
using namespace std;
#define LL long long
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 100010
int Bsize,N,Q,a[MAXN];
namespace BlockLists
{
#define BN 5010
struct BLNode{int next,data[],tag,tmp[],size,maxx,minn,del; LL sum; bool rev;}B[BN];
int start,ID;
queue<int>trash;
inline int New() {if (trash.empty()) return ++ID; int tmp=trash.front(); trash.pop(); return tmp;}
inline void Del(int x) {trash.push(x); B[x].next=-; B[x].size=B[x].maxx=B[x].minn=B[x].sum=B[x].tag=B[x].rev=B[x].del=;}
inline int GetP(int rk) {int p; for (p=start; ~B[p].next && rk>B[p].size; p=B[p].next) rk-=B[p].size; return p;}
inline int GetK(int rk) {int p; for (p=start; ~B[p].next && rk>B[p].size; p=B[p].next) rk-=B[p].size; return rk;}
inline void PushDown(int x)
{
int sz=B[x].size;
if (B[x].del) {int del=B[x].del; B[x].del=; for (int i=; i<=sz; i++) B[x].data[i]=del; B[x].sum=sz*del;}
if (B[x].rev) {reverse(B[x].data+,B[x].data+sz+); B[x].rev^=;}
if (B[x].tag) {int tag=B[x].tag; B[x].tag=; for (int i=; i<=sz; i++) B[x].data[i]+=tag; B[x].sum+=(LL)sz*tag;}
}
inline void Update(int x)
{
int sz=B[x].size; B[x].sum=;
for (int i=; i<=sz; i++) B[x].sum+=B[x].data[i],B[x].tmp[i]=B[x].data[i];
sort(B[x].tmp+,B[x].tmp+sz+);
B[x].minn=B[x].tmp[],B[x].maxx=B[x].tmp[B[x].size];
}
inline void Split(int pos,int rk)
{
PushDown(pos);
int id=New(); for (int i=rk; i<=B[pos].size; i++) B[id].data[++B[id].size]=B[pos].data[i]; B[id].next=B[pos].next;
B[pos].next=id; B[pos].size=max(rk-,);
Update(id); Update(pos);
}
inline void Merge(int pos)
{
for ( ; ~pos; pos=B[pos].next)
for (int suf=B[pos].next; ~suf && B[pos].size+B[suf].size<=Bsize; suf=B[suf].next)
{
PushDown(pos),PushDown(suf);
for (int k=; k<=B[suf].size; k++) B[pos].data[++B[pos].size]=B[suf].data[k];
B[pos].next=B[suf].next,Del(suf),Update(pos);
}
}
inline void Insert(int s,int x)
{
int now=GetP(s+),pos=GetK(s+); Split(now,pos);
B[now].data[++B[now].size]=x; Update(now); Merge(now);
}
inline void Delete(int s)
{
int now=GetP(s),pos=GetK(s); PushDown(now);
for (int i=pos+; i<=B[now].size; i++) B[now].data[i-]=B[now].data[i]; B[now].size--;
Update(now),Merge(now);
}
inline void Prework(int l,int r,int &x,int &y)
{
int now1=GetP(l),pos1=GetK(l); Split(now1,pos1);
int now2=GetP(r+),pos2=GetK(r+); Split(now2,pos2);
x=now1,y=GetP(r);
}
int st[MAXN];
inline void Rever(int l,int r)
{
int x,y,top=; Prework(l,r,x,y);
for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) st[++top]=i,B[i].rev^=;
B[st[]].next=B[y].next;
for (int i=top; i>; i--) B[st[i]].next=st[i-];
B[x].next=y; Merge(x);
}
inline void Move(int l,int r,int k)
{
int x,y,z,tmp; Prework(l,r-k,x,z); Prework(r-k+,r,z,y);
tmp=B[x].next; B[x].next=B[z].next,B[z].next=B[y].next,B[y].next=tmp;
Merge(x);
}
inline void Add(int l,int r,int D)
{
int x,y; Prework(l,r,x,y);
for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) B[i].sum+=(LL)B[i].size*D,B[i].tag+=D;
Merge(x);
}
inline void Modify(int l,int r,int val)
{
int x,y; Prework(l,r,x,y);
for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) B[i].tag=,B[i].del=val,B[i].sum=(LL)B[i].size*val;
Merge(x);
}
inline LL GetSum(int l,int r)
{
int x,y; LL re=; Prework(l,r,x,y);
for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) re+=B[i].sum;
Merge(x); return re;
}
#define INF 0x7fffffff
inline int GetRange(int l,int r)
{
int x,y,maxx=-INF,minn=INF; Prework(l,r,x,y);
for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next)
if (B[i].del) maxx=max(maxx,B[i].del+B[i].tag),minn=min(minn,B[i].del+B[i].tag);
else maxx=max(maxx,B[i].maxx+B[i].tag),minn=min(minn,B[i].minn+B[i].tag);
Merge(x); return maxx-minn;
}
inline int GetClose(int l,int r,int val)
{
int x,y,re=INF; Prework(l,r,x,y);
for (int t,i=B[x].next; ~i && i!=B[y].next; i=B[i].next)
if (B[i].del) re=min(re,abs(val-(B[i].del+B[i].tag)));
else
{
t=lower_bound(B[i].tmp+,B[i].tmp+B[i].size+,val-B[i].tag)-B[i].tmp;
if (t!=B[i].size+) re=min(re,abs(B[i].tmp[t]+B[i].tag-val));
if (t!=) re=min(re,abs(val-(B[i].tmp[t-]+B[i].tag)));
}
Merge(x); return re;
}
inline int GetKth(int l,int r,int k)
{
int x,y,t=-INF; Prework(l,r,x,y);
for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next) t=max(t,B[i].del? B[i].del+B[i].tag:B[i].maxx+B[i].tag);
int L=,R=t;
while (L<R)
{
int mid=((L+R)>>)+,re=;
for (int i=B[x].next; ~i && i!=B[y].next; i=B[i].next)
if (B[i].del) if (B[i].del+B[i].tag<mid) re+=B[i].size; else;
else t=upper_bound(B[i].tmp+,B[i].tmp+B[i].size+,mid--B[i].tag)-B[i].tmp,re+=max(,t-);
if (k>=re) L=mid; else R=mid-;
}
Merge(x); return L;
}
inline int GetSmall(int l,int r,int val)
{
int x,y,re=; Prework(l,r,x,y);
for (int t,i=B[x].next; ~i && i!=B[y].next; i=B[i].next)
if (B[i].del) if (B[i].del+B[i].tag<val) re+=B[i].size; else;
else t=upper_bound(B[i].tmp+,B[i].tmp+B[i].size+,val-B[i].tag-)-B[i].tmp,re+=t-;
Merge(x); return re;
}
inline void Init() {start=; ID=; B[].next=-; B[].size=;}
}
using namespace BlockLists;
int main()
{
// freopen("data.in","r",stdin);
// freopen("ORZJRY.out","w",stdout);
int N=read();
Init();
for (int x,i=; i<=N; i++) x=read(),Insert(i-,x);
Bsize=sqrt(N+(rand()%((int)sqrt(N))) );
Q=read();
while (Q--)
{
// puts("=============================================");
int opt=read(); int x,y,k;
// printf("%d :",opt);
switch (opt)
{
case : x=read(),k=read(),Insert(x,k); break;
case : x=read(); Delete(x); break;
case : x=read(),y=read(); Rever(x,y); break;
case : x=read(),y=read(),k=read(); Move(x,y,k); break;
case : x=read(),y=read(),k=read(); Add(x,y,k); break;
case : x=read(),y=read(),k=read(); Modify(x,y,k); break;
case : x=read(),y=read(); printf("%lld\n",GetSum(x,y)); break;
case : x=read(),y=read(); printf("%d\n",GetRange(x,y)); break;
case : x=read(),y=read(),k=read(); printf("%d\n",GetClose(x,y,k)); break;
case : x=read(),y=read(),k=read(); printf("%d\n",GetKth(x,y,k)); break;
case : x=read(),y=read(),k=read(); printf("%d\n",GetSmall(x,y,k)); break;
}
// puts("");
}
return ;
}
char哥说的对,用数组的我,BZOJ开O2是挽救不了我的....然后我自测AC...无限TLE....
已经生无可恋了。
【BZOJ-3337】ORZJRY I 块状链表的更多相关文章
- BZOJ 1507 Editor(块状链表)
		题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1507 题意:一个文本编辑器,模拟以下操作: 思路:块状链表的主要操作: (1)find( ... 
- [BZOJ3337] ORZJRY I --块状链表大毒瘤
		link 题目大意:维护一个序列 支持: 1.单点插入 2.单点删除 3.区间翻转 4.区间旋转 5.区间加 6.区间赋值 7.询问区间和 8.询问区间极差 9.询问区间与给定某个数差值绝对值的最小值 ... 
- 【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor   块状链表模板题
		2016-06-18 当时关于块状链表的想法是错误的,之前维护的是一个动态的$\sqrt{n}$,所以常数巨大,今天才知道原因TwT,请不要参照这个程序为模板!!! 模板题水啊水~~~ 第一次写块状链 ... 
- BZOJ 4864: [BeiJing 2017 Wc]神秘物质 (块状链表/平衡树 )
		这就是一道数据结构裸题啊,最大极差就是区间最大值减最小值,最小极差就是相邻两个数差的最小值.然后平衡树splay/treap或者块状链表维护就行了. 第一次自己写块状链表,蛮好写,就是长..然后就BZ ... 
- bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)
		[题意] 回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]. [思路] 考虑使用块状链表实现莫队算法中的插入与删除. 因为权值处于1..n之间,所以我们可以建一个基 ... 
- 块状链表 bzoj 3343教主的魔法
		//块状链表//分块排序,然后每次查找时在暴力查找头和尾两个块.//中间那些块,因为有序所以只需2分查找即可.我用的是lower_pound();//插入是,也是头和尾暴力插入,中间那些加到一个累计里 ... 
- BZOJ 3217: ALOEXT (块状链表套trie)
		第一次写块状链表,发现还挺好写的,但是一点地方写错加上强制在线就会各种姿势WA/TLE/RE爆- 想法就是分块后,在每一个块上维护最大值和次大值,还在每一个块上维护一棵trie树来求异或最大值.散块直 ... 
- 【函数式权值分块】【块状链表】bzoj3065 带插入区间K小值
		显然是块状链表的经典题.但是经典做法的复杂度是O(n*sqrt(n)*log^2(n))的,出题人明确说了会卡掉. 于是我们考虑每个块内记录前n个块的权值分块. 查询的时候差分什么的,复杂度就是O(n ... 
- 【BZOJ-1507】Editor    块状链表
		1507: [NOI2003]Editor Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 3397 Solved: 1360[Submit][Stat ... 
随机推荐
- PAT 1024. 科学计数法 (20)
			科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]"."[0-9]+E[+-][0-9]+,即数字的整数部分只有1位,小数部分至少有1位 ... 
- ISAPI_Rewrite中文手册
			参考:http://blog.csdn.net/fanxiaojie119/article/details/5353186 第一章:软件介绍ISAPI_Rewrite 是一款适用于IIS的功能强大的基 ... 
- 教你如何调用百度编辑器ueditor的上传图片、上传文件等模块
			出于兴趣爱好,前段时间自己尝试写了一个叫simple的cms,里面使用了百度ueditor编辑器,发现它的多图片上传模块很不错,用起来很方便,又可以选择已经上传好的图片.正好我又是个懒人,发现有现成的 ... 
- jquery选择器空格与大于号、加号与波浪号的区别
			空格:$('parent childchild')表示获取parent下的所有的childchild节点,所有的子孙. 大于号:$('parent > child')表示获取parent下的所有 ... 
- 程序开发使用docker部署
			我们公司自己研发了一套 grand-line 系统,使用 docker 来部署项目. 我是第一批小白鼠,一开始网络差,build 一次要半个小时,连接进入 web shell 也很慢,部署一个微信项目 ... 
- hadoop 2.6伪分布安装
			hadoop 2.6的“伪”分式安装与“全”分式安装相比,大部分操作是相同的,主要区别在于不用配置slaves文件,而且其它xxx-core.xml里的参数很多也可以省略,下面是几个关键的配置: (安 ... 
- java:使用匿名类直接new接口
			java中的匿名类有一个倍儿神奇的用法,见下面代码示例: package contract; public interface ISay { void sayHello(); } 上面是一个简单的接口 ... 
- opencv5-objdetect之级联分类器
			这是<opencv2.4.9tutorial.pdf>的objdetect module的唯一一个例子. 在opencv中进行人脸或者人眼 或者身体的检测 首先就是训练好级联分类器,然后就 ... 
- 数据契约(DataContract)及序列化指定输出字段
			服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所 ... 
- nios II--实验3——led 100M硬件部分
			led_100M 硬件开发 新建原理图 参照实验二(led) QSys调用模块 参照实验二(led) 原理图添加IP模块 参照实验二(led),在调用PLL的时候需要修改系统和SDRAM的时钟频率为1 ... 
