【BZOJ】1500: [NOI2005]维修数列(splay+变态题)
http://www.lydsy.com/JudgeOnline/problem.php?id=1500
模板不打熟你确定考场上调试得出来?
首先有非常多的坑点。。。我遇到的第一个就是,如何pushup。。。。。。。。。。。。sad。。
写了一大串。。。可是感觉。。。写不下去了。。。看别人怎么写吧。。。
orz
首先这个节点代表的这个区间我们维护mxl和mxr表示整个区间从左向右和从右向左能得到的最大序列和。。
然后我无脑不思考没有用好我们的定义,写了一大串的转移。。。
其实就是几个字。。
- void pushup() {
- s=1+ch[0]->s+ch[1]->s;
- sum=ch[0]->sum+ch[1]->sum+w;
- int l=max(0, ch[1]->mxl), r=max(0, ch[0]->mxr); //这里一定要注意
- mxl=max(ch[0]->mxl, ch[0]->sum+w+l); //不单独考虑ch[0]->sum的原因是我们假设了ch[0]->mxl是最优了
- mxr=max(ch[1]->mxr, ch[1]->sum+w+r);
- mx=max(l+w+r, max(ch[0]->mx, ch[1]->mx));
- }
555
然后有很多坑点我在注释里写。首先我的区间翻转那里我老是写错,我的getrange(l, r)是将区间l~r旋转到keytree那里,所以root是l-1,root->ch[1]是r+1,然后如果是要在某个点后边插入是getrange(pos+1, pos),一定要注意!
然后是pushdown的坑点,原来一直是写先tag后操作,现在变成了先操作后tag的形式,这点很重要!!!因为我们维护的size是整棵树的,当只有旋转到keytree下时,size不会统计到边界端点,所以整棵子树的size都是正确的!所以必须要在旋转回去前维护好所有的信息,而不是先打tag!一定要注意!!!之前一直调试不出来就是因为一直在考虑边界点怎么怎么影响。。。。。。然后各种搞不出来。。于是就这么简单的解决了orz
然后有一个地方我忘记了,,,就是每一个从树中获取信息的并向子树走的一定要pushdown!!我被select那里没有pushdown坑了好久
然后注意每一次更新子树后要pushup或者splay!!!一定要注意!!
还有询问前一定要将区间翻转后在区间进行查询!!!!一定要注意!!!
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <string>
- #include <iostream>
- #include <algorithm>
- #include <queue>
- #include <set>
- #include <map>
- using namespace std;
- typedef long long ll;
- #define rep(i, n) for(int i=0; i<(n); ++i)
- #define for1(i,a,n) for(int i=(a);i<=(n);++i)
- #define for2(i,a,n) for(int i=(a);i<(n);++i)
- #define for3(i,a,n) for(int i=(a);i>=(n);--i)
- #define for4(i,a,n) for(int i=(a);i>(n);--i)
- #define CC(i,a) memset(i,a,sizeof(i))
- #define read(a) a=getint()
- #define print(a) printf("%d", a)
- #define dbg(x) cout << (#x) << " = " << (x) << endl
- #define error(x) (!(x)?puts("error"):0)
- inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
- const int oo=~0u>>2;
- int n, m;
- struct node *null;
- struct node {
- node *ch[2], *fa;
- bool rev, tag;
- int sum, s, mx, mxl, mxr, w;
- void pushup() {
- s=1+ch[0]->s+ch[1]->s;
- sum=ch[0]->sum+ch[1]->sum+w;
- int l=max(0, ch[1]->mxl), r=max(0, ch[0]->mxr);
- mxl=max(ch[0]->mxl, ch[0]->sum+w+l);
- mxr=max(ch[1]->mxr, ch[1]->sum+w+r);
- mx=max(l+w+r, max(ch[0]->mx, ch[1]->mx));
- }
- void upd(const int &k) {
- if(this==null) return;
- w=k;
- sum=s*k;
- mx=mxl=mxr=max(k, k*s);
- tag=true;
- }
- void upd2() {
- if(this==null) return;
- rev=!rev;
- swap(ch[0], ch[1]);
- swap(mxl, mxr);
- }
- void pushdown() {
- if(rev) {
- rev=false;
- ch[0]->upd2();
- ch[1]->upd2();
- }
- if(tag) {
- tag=false;
- ch[0]->upd(w);
- ch[1]->upd(w);
- }
- }
- bool d() { return fa->ch[1]==this; }
- void setc(node *c, bool d) { ch[d]=c; c->fa=this; }
- void init(const int &k) { sum=mx=mxl=mxr=w=k; }
- void set(int c=0) { ch[0]=ch[1]=fa=null; rev=tag=false; sum=w=mx=mxl=mxr=c; s=1; }
- }*root, *s[1000005];
- void rot(node *x) {
- node *fa=x->fa;
- fa->pushdown(); x->pushdown(); bool d=x->d();
- fa->fa->setc(x, fa->d());
- fa->setc(x->ch[!d], d);
- x->setc(fa, !d);
- fa->pushup();
- if(fa==root) root=x;
- }
- void splay(node *x, node *fa=null) {
- x->pushdown();
- while(x->fa!=fa)
- if(x->fa->fa==fa) rot(x);
- else x->d()==x->fa->d()?(rot(x->fa), rot(x)):(rot(x), rot(x));
- x->pushup();
- }
- node *sel(node *x, const int &k) {
- x->pushdown();
- int s=x->ch[0]->s;
- if(s==k) return x;
- if(k>s) return sel(x->ch[1], k-s-1); return sel(x->ch[0], k);
- }
- node *getrange(const int &l, const int &r) {
- splay(sel(root, l-1));
- splay(sel(root, r+1), root);
- return root->ch[1];
- }
- int top;
- node *newnode(int c=0) {
- node *ret;
- if(top) ret=s[top--];
- else ret=new node;
- ret->set(c);
- return ret;
- }
- void build(node *&x, const int &l, const int &r) {
- if(l>r) return;
- x=newnode();
- if(l==r) { x->init(getint()); return; }
- int m=(l+r)>>1;
- build(x->ch[0], l, m-1);
- x->init(getint());
- build(x->ch[1], m+1, r);
- if(l<=m-1) x->ch[0]->fa=x;
- if(m+1<=r) x->ch[1]->fa=x;
- x->pushup();
- }
- void insert() {
- int pos=getint(), tot=getint();
- node *x;
- build(x, 1, tot);
- node *fa=getrange(pos+1, pos); //注意getrange的地方
- fa->setc(x, 0);
- root->ch[1]->pushup();
- root->pushup();
- }
- void cln(node *x) {
- if(x==null) return;
- cln(x->ch[0]);
- cln(x->ch[1]);
- s[++top]=x;
- }
- void dele() {
- int l=getint(), r=l+getint()-1;
- node *fa=getrange(l, r);
- cln(fa->ch[0]);
- fa->ch[0]=null;
- root->ch[1]->pushup();
- root->pushup();
- }
- void ask1() {
- int l=getint(), r=l+getint()-1;
- node *x=getrange(l, r)->ch[0];
- printf("%d\n", x->sum);
- }
- void ask2() {
- node *x=getrange(1, root->s-2)->ch[0];
- printf("%d\n", x->mx);
- }
- void fix1() {
- int l=getint(), r=l+getint()-1, c=getint();
- node *x=getrange(l, r)->ch[0];
- x->upd(c);
- root->ch[1]->pushup();
- root->pushup();
- }
- void fix2() {
- int l=getint(), r=l+getint()-1;
- node *x=getrange(l, r)->ch[0];
- x->upd2();
- root->ch[1]->pushup();
- root->pushup();
- }
- void init() {
- null=newnode(-oo);
- null->ch[0]=null->ch[1]=null->fa=null; null->s=null->sum=null->w=0;
- root=newnode();
- node *c=newnode();
- root->setc(c, 1);
- node *t;
- build(t, 1, n);
- root->ch[1]->setc(t, 0);
- root->ch[1]->pushup();
- root->pushup();
- }
- int main() {
- read(n); read(m);
- init();
- char s[15];
- for1(i, 1, m) {
- scanf("%s", s+1);
- char ch=s[3];
- if(ch=='S') insert(); //INSERT
- else if(ch=='L') dele(); //DELETE
- else if(ch=='T') ask1(); //GET-SUM
- else if(ch=='X') ask2(); //MAX-SUM
- else if(ch=='K') fix1(); //MAKE-SAME
- else if(ch=='V') fix2(); //REVERSE
- //P(root, 1);
- }
- return 0;
- }
Description
Input
输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。第2行包含N个数字,描述初始时的数列。以下M行,每行一条命令,格式参见问题描述中的表格。
Output
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。
Sample Input
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
Sample Output
10
1
10
HINT
Source
【BZOJ】1500: [NOI2005]维修数列(splay+变态题)的更多相关文章
- bzoj 1500: [NOI2005]维修数列 splay
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 6556 Solved: 1963[Submit][Status ...
- BZOJ 1500: [NOI2005]维修数列 (splay tree)
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 4229 Solved: 1283[Submit][Status ...
- bzoj1500: [NOI2005]维修数列 (Splay+变态题)
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 11353 Solved: 3553 [Submit][Status][Discuss] Descrip ...
- [BZOJ 1500] [NOI2005] 维修数列
题目链接:BZOJ - 1500 题目分析 我要先说一下,这道题我写了一晚上,然后Debug了一整个白天..........再一次被自己的蒟蒻程度震惊= = 这道题是传说中的Splay维护数列的Bos ...
- BZOJ 1500 [NOI2005]维修数列 FHQ Treap
终于A了这题...这题还是很好...但是我太菜...重构了三遍qwq FHQ Treap大法好!qwq...~~ Ins:直接拿输入造一棵树,把原来的树split成[1,pos],[pos+1,n], ...
- 【BZOJ1500】[NOI2005]维修数列 Splay
[BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行 ...
- 【BZOJ】1500: [NOI2005]维修数列
[算法]splay [题解]数据结构 感谢Occult的模板>_<:HYSBZ 1500 维修数列 #include<cstdio> #include<cctype> ...
- BZOJ1500 [NOI2005]维修数列(Splay tree)
[Submit][Status][Discuss] Description 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格 Inp ...
- BZOJ1500: [NOI2005]维修数列[splay ***]
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 12278 Solved: 3880[Submit][Statu ...
随机推荐
- JavaScript数组方法说明
JavaScript的数组方法有: http://www.w3school.com.cn/jsref/jsref_obj_array.asp 其中:concat.join和slice方法都不会修改原数 ...
- 解决Android 5.1系统以上通知状态栏小图标仅仅显示白色问题
看上图,想必大家都有遇到过吧.近期俺也遇到了,找到了解决方法,如今分享下也做个记录哈. 问题发生的规则是Android5.1或者以上的手机系统使用了非常多的颜色的通知图标,就会出现,怎么解决呢,非常e ...
- 具有SSM框架的CRUD与多条件查询
概述 居于ssm版本的crud跟多添加查询, 并带分页的demo 详细 代码下载:http://www.demodashi.com/demo/13653.html 一.功能展示 部门CRUD: 员工C ...
- android多线程进度条
多线程实现更新android进度条. 实例教程,详细信息我已经注释 android多线程进度条 01package com.shougao.hello; 02 03import android ...
- 摘:LIB和DLL的区别与在VC中的使用
共有两种库:一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library.一种是LIB包含函数 ...
- android何如获取SIM卡提供国家代码(ISO)
TelephonyManager telManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); telMana ...
- 基于Bootstrap的Asp.net Mvc 分页的实现(转)
最近写了一个mvc 的 分页,样式是基于 bootstrap 的 ,提供查询条件,不过可以自己写样式根据个人的喜好,以此分享一下.首先新建一个Mvc 项目,既然是分页就需要一些数据,我这 边是模拟了一 ...
- Android自己定义截屏功能,相似QQ截屏
由于公司业务需求 须要对一个屏幕进行截屏.但自带的截屏功能是远远不够项目的功能需求 ,我们是做一个画板软件 .须要的像QQ那样截屏之后 ,能够看到我们自己定义的工具.有画笔,button等等 .and ...
- python 中写hive 脚本
1.直接执行.sql脚本 import numpy as np import pandas as pd import lightgbm as lgb from pandas import DataFr ...
- B/S打印解决方案参考
使用Lodop 插件,该插件占用8000端口,未使用过,仅知依赖浏览器打印 http://blog.csdn.net/harderxin/article/details/17262945 强大的web ...