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取替。
Q x y: 输出区间[x,y]的最大字段和。
分析:
其实这题是BZOJ 1500 [NOI2005]维修数列这题的简化版。
使用splay来做非常简单。
我的做法增加一个虚拟节点在数列的最开始处,增加两个虚拟节点在最后,这是为了方便在数列最后插入的操作。
splay网上的资料比较多,其实splay比sbt、avl都简单。这里有我的一份总结,并且有一些资料: splay总结
囧,我写的splay太慢了,最后上网搜了一个IO外挂才过了。
- #include <set>
- #include <map>
- #include <list>
- #include <cmath>
- #include <queue>
- #include <stack>
- #include <string>
- #include <vector>
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- typedef long long ll;
- typedef unsigned long long ull;
- #define debug puts("here")
- #define rep(i,n) for(int i=0;i<n;i++)
- #define rep1(i,n) for(int i=1;i<=n;i++)
- #define REP(i,a,b) for(int i=a;i<=b;i++)
- #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
- #define pb push_back
- #define RD(n) scanf("%d",&n)
- #define RD2(x,y) scanf("%d%d",&x,&y)
- #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
- #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
- #define All(vec) vec.begin(),vec.end()
- #define MP make_pair
- #define PII pair<int,int>
- #define PQ priority_queue
- #define cmax(x,y) x = max(x,y)
- #define cmin(x,y) x = min(x,y)
- #define Clear(x) memset(x,0,sizeof(x))
- /*
- #pragma comment(linker, "/STACK:1024000000,1024000000")
- int size = 256 << 20; // 256MB
- char *p = (char*)malloc(size) + size;
- __asm__("movl %0, %%esp\n" :: "r"(p) );
- */
- /******** program ********************/
- const int MAXN = 210005;
- const int INF = 1e9;
- int ch[MAXN][2],fa[MAXN],sz[MAXN],root,tot;
- int sum[MAXN],val[MAXN];
- int lmax[MAXN],rmax[MAXN],mmax[MAXN];
- int a[MAXN];
- #define lx ch[x][0]
- #define rx ch[x][1]
- #define px fa[x]
- #define ly ch[y][0]
- #define ry ch[y][1]
- #define py fa[y]
- #define lz ch[z][0]
- #define rz ch[z][1]
- #define pz fa[z]
- #define rt ch[root][1]
- #define lrt ch[rt][0]
- #define rrt ch[rt][1]
- // 调试
- void dfs(int x){
- if(x){
- int a = ch[x][0];
- int b = ch[x][1];
- dfs(a);
- printf("x: %3d %3d %3d ",x,a,b);
- printf("val: %3d\n",val[x]);
- dfs(b);
- }
- }
- void gdb(){
- puts("\n---------------------");
- dfs(root);
- puts("---------------------\n");
- }
- inline void update(int x){
- if(!x)return;
- sz[x] = sz[lx]+sz[rx]+1;
- sum[x] = sum[lx]+sum[rx]+val[x];
- lmax[x] = max( lmax[lx] , sum[lx]+val[x]+max(0,lmax[rx]) );
- rmax[x] = max( rmax[rx] , sum[rx]+val[x]+max(0,rmax[lx]) );
- mmax[x] = max( mmax[lx] , mmax[rx] );
- mmax[x] = max( mmax[x] , max(0,lmax[rx])+val[x]+max(0,rmax[lx]) );
- }
- inline int sgn(int x){
- return ch[px][1]==x;
- }
- inline void setc(int y,int d,int x){
- ch[y][d] = x;
- px = y;
- }
- inline void rot(int x,int d){
- int y = px;
- int z = py;
- setc(y,!d,ch[x][d]);
- if(z) setc(z,sgn(y),x);
- fa[x] = z;
- setc(x,d,y);
- update(y);
- }
- inline void splay(int x,int goal=0){
- if(!x)return;
- while(px!=goal){
- int y = px;
- int z = py;
- if(z==goal){
- rot(x,!sgn(x));
- break;
- }
- if(lz==y){
- if(ly==x)
- rot(y,1),rot(x,1);
- else
- rot(x,0),rot(x,1);
- }
- else{
- if(ry==x)
- rot(y,0),rot(x,0);
- else
- rot(x,1),rot(x,0);
- }
- }
- update(x);
- if(goal==0)
- root = x;
- }
- inline void newNode(int &x,int y,int v){
- x = ++ tot;
- sz[x] = 1;
- ch[x][0] = ch[x][1] = 0;
- val[x] = sum[x] = lmax[x] = rmax[x] = mmax[x] = v;
- fa[x] = y;
- }
- inline void build(int &x,int y,int l,int r){
- if(l>r) return;
- int mid = (l+r)>>1;
- newNode(x,y,a[mid]);
- build(lx,x,l,mid-1);
- build(rx,x,mid+1,r);
- update(x);
- }
- inline int getKth(int x,int k){
- while( sz[lx]+1 != k ){
- if(k<=sz[lx])x = lx;
- else{
- k -= sz[lx]+1;
- x = rx;
- }
- }
- return x;
- }
- inline void splay(int x,int y,int ok){
- splay( getKth(root,x) );
- splay( getKth(root,y) , root );
- }
- inline void Int(int &num){
- char in;
- bool neg=false;
- while(((in=getchar()) > '9' || in<'0') && in!='-') ;
- if(in=='-'){
- neg=true;
- while((in=getchar()) >'9' || in<'0');
- }
- num=in-'0';
- while(in=getchar(),in>='0'&&in<='9')
- num*=10,num+=in-'0';
- if(neg)
- num=0-num;
- }
- char Char() {
- char res;
- while (res = getchar(), !isalpha(res));
- return res;
- }
- char s[MAXN<<2];
- int cur;
- inline int Int(){
- int ans = 0;
- bool ok = 0 , f = 0;
- for(;s[cur];cur++){
- if(s[cur]==' '){
- if(f)break;
- continue;
- }f = true;
- if(s[cur]=='-')ok = true;
- else ans = ans*10+s[cur]-'0';
- }
- if(ok)ans = -ans;
- return ans;
- }
- int main(){
- #ifndef ONLINE_JUDGE
- freopen("sum.in","r",stdin);
- //freopen("sum.out","w",stdout);
- #endif
- int n,m,x,y;
- char op;
- RD(n);
- rep1(i,n)
- Int(a[i]);
- lmax[0] = mmax[0] = rmax[0] = -INF;
- a[++n] = INF; // 补一个虚拟节点,方便在最后插入
- newNode(root,0,-INF);
- newNode(ch[root][1],root,INF);
- update(rt);
- update(root);
- build(lrt,rt,1,n);
- update(rt);
- update(root);
- RD(m);
- while(m--){
- op = Char();
- Int(x);
- if(op=='I'){
- Int(y);
- splay(x,x+1,0);
- newNode(lrt,rt,y);
- update(rt);
- update(root);
- }else if(op=='D'){
- splay(x,x+2,0);
- fa[lrt] = 0;
- lrt = 0;
- }else if(op=='R'){
- Int(y);
- splay(x,x+2,0);
- fa[lrt] = 0;
- lrt = 0;
- newNode(lrt,rt,y);
- }else{
- Int(y);
- splay(x,y+2,0);
- printf("%d\n",mmax[lrt]);
- }
- }
- return 0;
- }
GSS6 4487. Can you answer these queries VI splay的更多相关文章
- SPOJ 4487. Can you answer these queries VI splay
题目链接:点击打开链接 题意比較明显,不赘述. 删除时能够把i-1转到根,把i+1转到根下 则i点就在 根右子树 的左子树,且仅仅有i这一个 点 #include<stdio.h> #in ...
- spoj 4487. Can you answer these queries VI (gss6) splay 常数优化
4487. Can you answer these queries VI Problem code: GSS6 Given a sequence A of N (N <= 100000) in ...
- SPOJ GSS6 Can you answer these queries VI ——Splay
[题目分析] 增加了插入和删除. 直接用Splay维护就好辣! 写了一个晚上,(码力不精),最后发现更新写挂了 [代码] #include <cstdio> #include <cs ...
- 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 ...
- SP4487 GSS6 - Can you answer these queries VI
题目大意 给出一个由N个整数组成的序列A,你需要应用M个操作: I p x 在 p 处插入插入一个元素 x D p 删除 p 处的一个元素 R p x 修改 p 处元素的值为 x Q l r 查询一 ...
- kuangbin专题七 HDU4027 Can you answer these queries? (线段树)
A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use ...
- 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 ...
- hdu 4027 Can you answer these queries?
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4027 Can you answer these queries? Description Proble ...
- GSS4 2713. Can you answer these queries IV 线段树
GSS7 Can you answer these queries IV 题目:给出一个数列,原数列和值不超过1e18,有两种操作: 0 x y:修改区间[x,y]所有数开方后向下调整至最近的整数 1 ...
随机推荐
- [转][IIS]发布网站,提示用户 'IIS APPPOOL\***' 登录失败。
链接:http://www.cnblogs.com/tianguook/p/3881075.html 用户 'IIS APPPOOL\DefaultAppPool' 登录失败. 我在windows8中 ...
- <创建和销毁对象>经验法则——考虑用静态工厂方法代替公有构造方法
一.引出静态工厂方法 对于java类而言,为了让使用者获取它自身的一个实例化对象,会有以下方法: 1.该类提供一个公有的构造方法.在这种情况下,程序可以通过多个“new 构造方法”语句来创建类的任意多 ...
- Chrome的JS调试工具
你是怎么调试 JavaScript 程序的?最原始的方法是用 alert() 在页面上打印内容,稍微改进一点的方法是用 console.log() 在 JavaScript 控制台上输出内容.嗯~,用 ...
- 译 - EF 6秘诀(第二版) - 目录
本博文系Entity Framework 6 Recipes, 2nd Edition的目录译文.保留原文,方便参考. 第一章 EF入门Chapter 1. Getting Started with ...
- Python抓取页面中超链接(URL)的三中方法比较(HTMLParser、pyquery、正则表达式) <转>
Python抓取页面中超链接(URL)的3中方法比较(HTMLParser.pyquery.正则表达式) HTMLParser版: #!/usr/bin/python # -*- coding: UT ...
- linux 硬链接和软链接(转)
1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。默认情况下,ln命令产生硬链接。 【硬连接】硬连接指通过索引节点 ...
- Codeforces Gym 100531D Digits 暴力
Problem D. Digits 题目连接: http://codeforces.com/gym/100531/attachments Description Little Petya likes ...
- 【JavaScript】关于javascript原型的深入理解
http://mozilla.com.cn/post/21667/ http://liuzhijun.iteye.com/blog/1157453 http://liuzhijun.iteye.com ...
- apache2.2 虚拟主机配置
一.改动httpd.conf 打开appserv的安装文件夹,找到httpd.conf文件,分别去掉以下两行文字前面的#号. #LoadModule vhost_alias_module module ...
- AutoCompleteTextView输入汉字拼音首字母实现过滤提示(支持多音字,Filterable的使用)
AutoCompleteTextView具有输入提示的功能,但是它的这种提示不适合对股票列表的过滤,如果你玩过股票软件,就会知道只要输入股票名称的首字母或股票代码就会出现符合匹配的股票,这种过滤怎么实 ...