spoj 4487. Can you answer these queries VI (gss6) splay 常数优化
4487. Can you answer these queries VIProblem code: GSS6 |
Given a sequence A of N (N <= 100000) integers, you have to apply Q (Q <= 100000) operations:
Insert, delete, replace an element, find the maximum contiguous(non empty) sum in a given interval.
Input
The first line of the input contains an integer N.
The following line contains N integers, representing the starting
sequence A1..AN, (|Ai| <= 10000).
The third line contains an integer Q. The next Q lines contains the operations in following form:
I x y: insert element y at position x (between x - 1 and x).
D x : delete the element at position x.
R x y: replace element at position x with y.
Q x y: print max{Ai + Ai+1 + .. + Aj | x <= i <= j <= y}.
All given positions are valid, and given values are between -10000 and +10000.
The sequence will never be empty.
Output
For each "Q" operation, print an integer(one per line) as described above.
Example
Input:
5
3 -4 3 -1 6
10
I 6 2
Q 3 5
R 5 -4
Q 3 5
D 2
Q 1 5
I 2 -10
Q 1 6
R 2 -1
Q 1 6 Output:
8
3
6
3
5 第二次写splay居然遇上了考splay的常数优化。弄了很久。首先是读入优化,貌似SPOJ上面数据有'\r'所以要特殊判断。然后inline所有函数,最后把splay移到一个struct里面会加速很多。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<string>
#include<queue>
using namespace std;
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define MAXN 110000
#define MAXV MAXN*2
#define MAXE MAXV*2
#define MAXT MAXN*2
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
#define lch splay[now].ch[0]
#define rch splay[now].ch[1]
typedef long long qword;
inline int nextInt()
{
char ch;
int x=;
bool flag=false;
do
ch=(char)getchar(),flag=(ch=='-')?true:flag;
while(ch<''||ch>'');
do x=x*+ch-'';
while (ch=(char)getchar(),ch<='' && ch>='');
return x*(flag?-:);
} int n,m;
int root=,topt=;;
struct sss
{
int lx,rx,mx,val,sum,siz,pnt;
int ch[];
}splay[MAXT];
inline void up(int now)
{
splay[now].lx=splay[now].rx=splay[now].mx=-INF;
if (lch)splay[now].lx=max(splay[now].lx,splay[lch].lx);
splay[now].lx=max(splay[now].lx,max(splay[lch].sum+splay[now].val,splay[lch].sum+splay[now].val+splay[rch].lx)); if (rch)splay[now].rx=max(splay[now].rx,splay[rch].rx);
splay[now].rx=max(splay[now].rx,max(splay[rch].sum+splay[now].val,splay[rch].sum+splay[now].val+splay[lch].rx)); splay[now].mx=splay[now].val;
if (lch)splay[now].mx=max(splay[now].mx,splay[lch].mx);
if (rch)splay[now].mx=max(splay[now].mx,splay[rch].mx);
splay[now].mx=max(splay[now].mx,splay[lch].rx+splay[rch].lx+splay[now].val);
splay[now].mx=max(splay[now].mx,splay[rch].lx+splay[now].val);
splay[now].mx=max(splay[now].mx,splay[lch].rx+splay[now].val); splay[now].siz=splay[lch].siz+splay[rch].siz+;
splay[now].sum=splay[lch].sum+splay[rch].sum+splay[now].val;
} inline void Rotate(int now)
{
int p=splay[now].pnt,anc=splay[p].pnt;
int dir=splay[p].ch[]==now;
if (anc)
splay[anc].ch[splay[anc].ch[]==p]=now;
splay[now].pnt=anc; splay[splay[now].ch[dir]].pnt=p;
splay[p].ch[-dir]=splay[now].ch[dir]; splay[p].pnt=now;
splay[now].ch[dir]=p;
up(p);
up(now);
}
/*
inline int Get_kth(int now,int rk)
{
if (rk==siz[splay[now].ch[0]]+1)
return now;
if (rk<siz[splay[now].ch[0]]+1)
return Get_kth(splay[now].ch[0],rk);
else
return Get_kth(splay[now].ch[1],rk-siz[splay[now].ch[0]]-1);
}*/
inline int Get_kth(int rk)
{
int now=root;
while (rk!=splay[splay[now].ch[]].siz+)
{
if (rk>splay[splay[now].ch[]].siz+)
{
rk-=splay[splay[now].ch[]].siz+;
now=splay[now].ch[];
}else
{
now=splay[now].ch[];
}
}
return now;
} inline void Splay(int now,int tp=)
{
if (now==tp)return ;
while (splay[now].pnt!=tp)
{
int p=splay[now].pnt,anc=splay[p].pnt;
if (anc==tp)
Rotate(now);
else if( (splay[anc].ch[]==p) == (splay[p].ch[]==now))
{
Rotate(p);
Rotate(now);
}else
{
Rotate(now);
Rotate(now);
}
}
if (tp==)root=now;
}
inline void Insert(int pos,int v)
{
int now=++topt;
splay[now].ch[]=splay[now].ch[]=;
splay[now].pnt=;
splay[now].val=v;
splay[now].siz=;
splay[now].lx=splay[now].rx=splay[now].mx=splay[now].sum=v;
if (!pos)
{
Splay(Get_kth());
splay[now].ch[]=root;
splay[root].pnt=now;
root=now;
up(now);
return ;
}
Splay(Get_kth(pos));
splay[now].pnt=root;
splay[now].ch[]=splay[root].ch[];
splay[splay[root].ch[]].pnt=now;
splay[root].ch[]=now;
up(now);
up(root);
return ;
}
inline void Delete(int pos)
{
Splay(Get_kth(pos));
if (pos!=splay[root].siz)
{
Splay(Get_kth(pos+),root);/**/
splay[splay[root].ch[]].ch[]=splay[root].ch[];
splay[splay[root].ch[]].pnt=splay[root].ch[];;
splay[splay[root].ch[]].pnt=splay[root].pnt;
root=splay[root].ch[];
}else
{
root=splay[root].ch[];
splay[root].pnt=;
}
up(root);
}
inline int Qry_mxs(int l,int r)
{
if (l== && r==splay[root].siz)
{
return splay[root].mx;
}else if (l==)
{
Splay(Get_kth(r+));
return splay[splay[root].ch[]].mx;
}else if (r==splay[root].siz)
{
Splay(Get_kth(l-));
return splay[splay[root].ch[]].mx;
}else
{
Splay(Get_kth(l-));
Splay(Get_kth(r+),root);
return splay[splay[splay[root].ch[]].ch[]].mx;
}
}
inline void Chg_val(int pos,int v)
{
Splay(Get_kth(pos));
splay[root].val=v;
up(root);
}
void Scan(int now)
{
if (!now)return ;
if (splay[now].siz!=splay[lch].siz+splay[rch].siz+)throw ;
if (splay[now].ch[])
{
if (splay[splay[now].ch[]].pnt!=now)throw ;
Scan(splay[now].ch[]);
}
printf("%d ",splay[now].val);
if (splay[now].ch[])
{
if (splay[splay[now].ch[]].pnt!=now)throw ;
Scan(splay[now].ch[]);
}
}
void Build_tree(int &now,int *num,int l,int r)
{
now=++topt;
int mid=(l+r)>>;
splay[now].siz=;
splay[now].sum=splay[now].val=splay[now].mx=splay[now].lx=splay[now].rx=num[mid];
if (l<=mid-)Build_tree(lch,num,l,mid-);
if (mid+<=r)Build_tree(rch,num,mid+,r);
splay[lch].pnt=now;
splay[rch].pnt=now;
up(now);
}
int num[MAXN];
int main()
{
freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int i,j,k;
int x,y,z;
scanf("%d",&n);
for (i=;i<n;i++)
{
x=nextInt();
num[i]=x;
}
Build_tree(root,num,,n-);
scanf("%d\n",&m);
char opt;
for (i=;i<m;i++)
{
opt=getchar();
//scanf("%c",&opt);
if (opt=='I')
{
// scanf("%d%d",&x,&y);
x=nextInt();y=nextInt();
x--;
Insert(x,y);
}else if (opt=='Q')
{
// scanf("%d%d",&x,&y);
x=nextInt();y=nextInt();
printf("%d\n",Qry_mxs(x,y));
}else if (opt=='R')
{
// scanf("%d%d",&x,&y);
x=nextInt();y=nextInt();
Chg_val(x,y);
}else if (opt=='D')
{
// scanf("%d",&x);
x=nextInt();
Delete(x);
}
getchar();
}
return ;
}
spoj 4487. Can you answer these queries VI (gss6) splay 常数优化的更多相关文章
- SPOJ 4487. Can you answer these queries VI splay
题目链接:点击打开链接 题意比較明显,不赘述. 删除时能够把i-1转到根,把i+1转到根下 则i点就在 根右子树 的左子树,且仅仅有i这一个 点 #include<stdio.h> #in ...
- GSS6 4487. Can you answer these queries VI splay
GSS6 Can you answer these queries VI 给出一个数列,有以下四种操作: I x y: 在位置x插入y.D x : 删除位置x上的元素.R x y: 把位置x用y取替 ...
- SPOJ GSS6 Can you answer these queries VI
Can you answer these queries VI Time Limit: 2000ms Memory Limit: 262144KB This problem will be judge ...
- SPOJ GSS3 Can you answer these queries III[线段树]
SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...
- GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树
GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...
- [题解] SPOJ GSS1 - Can you answer these queries I
[题解] SPOJ GSS1 - Can you answer these queries I · 题目大意 要求维护一段长度为 \(n\) 的静态序列的区间最大子段和. 有 \(m\) 次询问,每次 ...
- SPOJ 1557. Can you answer these queries II 线段树
Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...
- bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树
2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 145 ...
- spoj gss2 : Can you answer these queries II 离线&&线段树
1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang ...
随机推荐
- 无法定位序数XX于动态链接库XX.dll的解决的方法
问题阐述: 开发环境:VS2008 使用RELEASE生成了可执行文件,发如今某些电脑上能够正常执行,但在部分电脑中执行失败提示:无法定位序数8523于动态链接库mfc90.dll 在网上查找了一些资 ...
- 创业公司求IOS、Android攻城狮一枚
地点:北京CBD附近(地铁1号线大望路) 魅力值:送珍贵期权 你要会: 1. IOS或者Android开发 2.可以处理类似微视/秒拍的视频录制功能 3.熟悉jso ...
- ASP.NET Web API(一):使用初探,GET和POST数据
概述 REST(Representational State Transfer表述性状态转移)而产生的REST API的讨论越来越多,微软在ASP.NET中也添加了Web API的功能 项目建立 在安 ...
- Unity monodev环境搭建
断点调试功能可谓是程序员必备的功能了.Unity3D支持编写js和c#脚本,但很多人可能不知道,其实Unity3D也能对程序进行断点调试的.不过这个断点调试功能只限于使用Unity3D自带的MonoD ...
- 解决升级windows8.1 Oracle服务被刷新
1.调用CMD管理员模式,记得,否则你想要执行的东西都调用不了,win8下“窗口键+X”-“命令提示符(管理员) 2.创建oracle10g.11g的监听服务:(%ORACLE_HOME%为oracl ...
- Android(java)学习笔记186:对ListView等列表组件中数据进行增、删、改操作
1.ListView介绍 解决大量的相似的数据显示问题 采用了MVC模式: M: model (数据模型) V: view (显示的视图) C: controller 控制器 入门案例: acit ...
- linux lsof nmap netstat
lsof -i :22 # 显示22端口当前运行的程序 lsof -c ssh # 显示ssh进程打开的文件 lsof -p 2120 #显示进程id2120打开的文件 nmap -sP ...
- Vmare12(虚拟机)安装Mac OS X Yosemite 10.10
需要预备的软件如下: OSX10.10的系统镜像,下载好之后将后缀.cdr改成.iso,下载来源如下: 链接:http://pan.baidu.com/s/1sj4ri5R 密码:y86w un ...
- Ubuntu安装sar出错Please check if data collecting is enabled in /etc/default/sysstat
1.安装sysstat apt-get install sysstat 2.安装后无法使用: Cannot open /var/log/sysstat/sa02: No such file or di ...
- Spring Mvc session拦截器实现
Spring Mvc拦截器实现session过期跳转到登录页面 配置拦截器 <mvc:interceptors> <mvc:interceptor> <mvc:mappi ...