王学长的AAA树
让我们响应王学长的号召勇敢的分开写splay和lct吧!
分开写大法好!!!!!!!!!!!杜教的ch[4]弱爆了!!!!
#include <stdio.h>
#include <algorithm>
char ch;
inline void read(int &x)
{
x=;ch=getchar();
while(ch<=) ch=getchar();
while(ch>) x=x*+ch-,ch=getchar();
}; inline void G(int x){while(x--) getchar();} #define MAXN 50005
#define MAXM 250005 int n,q; struct Info{
int mi,size;
long long sum;
}; const int NULL_TAG=;
const Info NULL_INFO=(Info){,,}; inline Info operator + (const Info &a,const Info &b)
{
return (Info){std::min(a.mi,b.mi),a.size+b.size,a.sum+b.sum};
}; inline Info operator * (const Info &a,const int &b)
{
return a.size ? (Info){a.mi+b,a.size,a.sum+1LL*a.size*b}: a;
}; struct TopTree{ struct splay_node{
splay_node *ch[],*fa;
Info x,sum;
int tag,tag_sum; inline void add_tag(int t)
{
tag=tag+t;tag_sum=tag_sum+t;
x=x*t;sum=sum*t;
}; inline void down()
{
if(ch[]) ch[]->add_tag(tag);
if(ch[]) ch[]->add_tag(tag);
tag=NULL_TAG;
}; inline void update()
{
sum=x;
if(ch[]) sum=sum+ch[]->sum;
if(ch[]) sum=sum+ch[]->sum;
}; }; splay_node _nodes[MAXN]; inline int get_parent(splay_node *x,splay_node *&fa)
{
return (fa=x->fa) ? fa->ch[]==x : -;
}; inline void rotate(splay_node *x)
{
int t1,t2;
splay_node *fa,*gfa;
t1=get_parent(x,fa);
t2=get_parent(fa,gfa);
if((fa->ch[t1]=x->ch[t1^])) fa->ch[t1]->fa=fa;
fa->fa=x;x->fa=gfa;x->ch[t1^]=fa;
if(t2!=-) gfa->ch[t2]=x;
fa->update();
}; inline void pushdown(splay_node *x)
{
static splay_node *stack[MAXN];
int cnt=;
while(x) stack[cnt++]=x,x=x->fa;
while(cnt--) stack[cnt]-> down();
}; inline splay_node * splay(splay_node *x)
{
pushdown(x);
while(){
int t1,t2;
splay_node *fa,*gfa;
t1=get_parent(x,fa);
if(t1==-) break;
t2=get_parent(fa,gfa);
if(t2==-){
rotate(x);break;
}else if(t1==t2){
rotate(fa);rotate(x);
}else{
rotate(x);rotate(x);
};
};
x->update();
return x;
}; inline splay_node * join(splay_node *L,splay_node *R)
{
if(!L) return R;
if(!R) return L;
while(L->ch[]) L-> down(),L=L->ch[];
splay(L)->ch[]=R;
R->fa=L;
L->update();
return L;
}; static splay_node *root[MAXN]; struct lct_node{
lct_node *ch[],*fa,*first,*last;
bool rev; Info x,sum,tree,all;
int chain_tag,tree_tag; inline void add_rev_tag()
{
std::swap(ch[],ch[]);
std::swap(first,last);
rev^=;
}; inline void add_chain_tag(int t)
{
x=x*t;sum=sum*t;
chain_tag=chain_tag+t;
all=sum+tree;
}; inline void add_tree_tag(int t); inline void down()
{
if(rev){
if(ch[]) ch[]->add_rev_tag();
if(ch[]) ch[]->add_rev_tag();
rev=;
};
if(ch[]) ch[]->add_chain_tag(chain_tag),ch[]->add_tree_tag(tree_tag);
if(ch[]) ch[]->add_chain_tag(chain_tag),ch[]->add_tree_tag(tree_tag);
chain_tag=tree_tag=NULL_TAG;
}; inline void update();
}; static lct_node lct[MAXN]; inline int get_parent(lct_node *x,lct_node *&fa)
{
return (fa=x->fa) ? fa->ch[]==x?:fa->ch[]==x?:- : -;
}; inline void rotate(lct_node *x)
{
int t1,t2;
lct_node *fa,*gfa;
t1=get_parent(x,fa);
t2=get_parent(fa,gfa);
if((fa->ch[t1]=x->ch[t1^])) fa->ch[t1]->fa=fa;
fa->fa=x;x->fa=gfa;x->ch[t1^]=fa;
if(t2!=-) gfa->ch[t2]=x;
fa->update();
}; inline void pushdown(lct_node *x)
{
static lct_node *stack[MAXN];
int cnt=;
while(){
stack[cnt++]=x;
lct_node *fa=x->fa;
if(!fa || (fa->ch[]!=x && fa->ch[]!=x)) break;
x=fa;
};
while(cnt--) stack[cnt]-> down();
}; inline lct_node * splay(lct_node *x)
{
pushdown(x);
while(){
int t1,t2;
lct_node *fa,*gfa;
t1=get_parent(x,fa);
if(t1==-) break;
t2=get_parent(fa,gfa);
if(t2==-){
rotate(x);break;
}else if(t1==t2){
rotate(fa);rotate(x);
}else{
rotate(x);rotate(x);
};
};
x->update();
return x;
}; inline lct_node * access(lct_node *x);
inline void setroot(int x);
inline void modifychain(int x,int y,int t);
inline void modifysubtree(int x,int y,int t);
inline Info query_chain(int x,int y);
inline Info query_subtree(int x,int y);
inline void link(int x,int y);
inline void cut(int x,int y);
inline void init(int *a); }_toptree; TopTree::lct_node TopTree::lct[MAXN];
TopTree::splay_node *TopTree::root[MAXN]; inline void TopTree::lct_node::add_tree_tag(int t)
{
tree=tree*t;
tree_tag=tree_tag+t;
all=sum+tree;
int id=this-TopTree::lct;
if(root[id]){
root[id]->add_tag(t);
};
}; inline void TopTree::lct_node::update()
{
sum=x;tree=NULL_INFO;
int id=this-TopTree::lct;
if(root[id]){
tree=tree+root[id]->sum;
};
if(ch[]) sum=sum+ch[]->sum,tree=tree+ch[]->tree;
if(ch[]) sum=sum+ch[]->sum,tree=tree+ch[]->tree;
all=sum+tree;
first=ch[]?ch[]->first:this;
last=ch[]?ch[]->last:this;
}; inline TopTree::lct_node * TopTree::access(TopTree::lct_node *x)
{
TopTree::lct_node *ret=NULL;
while(x){
splay(x);
int X=x-TopTree::lct;
if(x->ch[]){
int id=x->ch[]->first-TopTree::lct;
splay_node *p=_nodes+id;
p->ch[]=root[X];
if(root[X]) root[X]->fa=p;
p->ch[]=NULL;
p->fa=NULL;
p->x=x->ch[]->all;
p->tag=p->tag_sum=NULL_TAG;
p->update();
root[X]=p;
x->ch[]=NULL;
};
if(ret){
int id=ret->first-TopTree::lct;
splay_node *p=_nodes+id;
splay(p);
if(p->ch[]) p->ch[]->fa=NULL;
if(p->ch[]) p->ch[]->fa=NULL;
root[X]=join(p->ch[],p->ch[]);
ret->add_chain_tag(p->tag_sum),ret->add_tree_tag(p->tag_sum);
x->ch[]=ret;
};
x->update();
ret=x;x=x->fa;
};
return ret;
}; inline void TopTree::setroot(int x)
{
access(TopTree::lct+x)->add_rev_tag();
}; inline void TopTree::modifychain(int x,int y,int t)
{
setroot(x);
access(TopTree::lct+y)->add_chain_tag(t);
}; inline void TopTree::modifysubtree(int x,int y,int t)
{
setroot(x);
access(TopTree::lct+y),splay(TopTree::lct+y);
TopTree::lct[y].x=TopTree::lct[y].x*t;
if(root[y]) root[y]->add_tag(t);
TopTree::lct[y].update();
}; inline Info TopTree::query_chain(int x,int y)
{
setroot(x);
return access(TopTree::lct+y)->sum;
}; inline Info TopTree::query_subtree(int x,int y)
{
setroot(x);
access(TopTree::lct+y),splay(TopTree::lct+y);
return root[y] ? TopTree::lct[y].x+root[y]->sum : TopTree::lct[y].x;
}; inline void TopTree::link(int x,int y)
{
setroot(x);
splay(TopTree::lct+x)->fa=TopTree::lct+y;
access(TopTree::lct+y);
splay(TopTree::lct+y)->ch[]=TopTree::lct+x;
TopTree::lct[y].update();
}; inline void TopTree::cut(int x,int y)
{
setroot(x);
access(TopTree::lct+y);
TopTree::lct_node *t=splay(TopTree::lct+y);
t->ch[]->fa=NULL;t->ch[]=NULL;
t->update();
}; inline void TopTree::init(int *a)
{
int i;
for(i=;i<=n;i++){
TopTree::lct[i].first=TopTree::lct[i].last=TopTree::lct+i;
TopTree::lct[i].x=TopTree::lct[i].sum=TopTree::lct[i].all=(Info){a[i],,a[i]};
TopTree::lct[i].tree=NULL_INFO;
TopTree::lct[i].chain_tag=TopTree::lct[i].tree_tag=NULL_TAG;
};
};
王学长的AAA树的更多相关文章
- 王学长的LCT标程
善良的王学长竟然亲自打了一遍QAQ好感动QAQ #include<iostream> #include<cstdio> #include<cmath> #inclu ...
- 杜教的AAA树
膜膜膜,常数挺小的... #include<iostream> #include<cstdio> #include<cmath> #include<algor ...
- BZOJ 3589 动态树(子树操作,链查询)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3589 题意:给出一棵有根树,两种操作:(1)以u为根的子树所有节点权值加上一个数字 ...
- COJ 0970 WZJ的数据结构(负三十)树分治
WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...
- COJ 0981 WZJ的数据结构(负十九)树综合
WZJ的数据结构(负十九) 难度级别:E: 运行时间限制:3500ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ的数据结构中有很多都是关于树的.这让很多练习 ...
- [模板] 动态树/LCT
简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...
- ZJOI 游记
在备战YZ提前招生考时去ZJOI玩了趟,ZJ果然人才辈出= =神犇讲课各种神听不懂啊orz day 0 Mon. 上午在AB班愉快地玩耍,下午就去HZ了. HZ真热啊... 学军也是节约= =空调都不 ...
- 22.Android之ExpandableListView树形列表学习
Android经常用到树形菜单,一般ExpandableListView可以满足这个需要,今天学习下. XML代码: <?xml version="1.0" encoding ...
- Vijos1901 学姐的钱包
描述 学姐每次出门逛街都要带恰好M元钱, 不过她今天却忘记带钱包了.可怜的doc只好自己凑钱给学姐, 但是他口袋里只有一元钱.好在doc的N位朋友们都特别有钱, 他们答应与doc作一些交换.其中第i位 ...
随机推荐
- JavaScript实现自定义短信模板
自定义短信模板,要求:可以插入关键字,当然是可以在点击到文本域中的任意位置,关键字以中括号包裹的形式出现[关键字],删除关键字要整个关键都删掉,而不是自己全删除. 详细在简书中 http://www. ...
- NetworkX学习笔记-5-NetworkX中怎样对多个网络赋属性,并根据属性排序
这是我在数据分析过程中遇到的实际问题,简单记录一下.这里以DiGraph为例,其他类型的网络(图)的处理方法是一样的. 按照这里:http://networkx.github.io/documenta ...
- 关于scanf的几种处理方法
字符输入中,赋值顺序和缓存的联系 scanf是从标准输入缓冲区中读取输入的数据,假设连续输入两个%c格式的字符.而中间又要涉及回车,那么第二个字符将被赋予回车. 解决的方法: .清空输入缓冲区 第一个 ...
- linux怎么给一个普通用户reboot权限?
分四种情况讨论:1.让任何人(包括根本不拥有系统帐号的人)都可以通过控制台reboot在/etc/inittab文件中保留ca::ctrlaltdel:/sbin/shutdown -t3 -r no ...
- Easyui弹出窗体在iframe的父级页面显示
今天做EasyUI学习的预到了一个这样的问题:通过iframe加载的一个页面在调用$.messager.alert();这个方法后只能在iframe中显示alert效果而不是在全局的页面上显示这并不我 ...
- [转] postgresql常用命令
PS: 数据库安装后,里面的每个数据库有自己的用户密码,需要dump的时候,指定用户pg_dump -U xxx <数据库> > 某个地址 最近一直在学习Postgresql,下面 ...
- nginx 2.基本配置
死磕nginx 2.基本配置 鉴于深入浅出的原理,我们先从一个简单的配置了解nginx的配置 1.一个典型配置 nginx的配置文件默认在nginx安装目录的conf二级目录下面,主配置文件为 ngi ...
- css过渡+3D
<!DOCTYPE html><html><head> <title>guodu</title> <meta charset=&quo ...
- PHP 错误处理
PHP 错误处理 在 PHP 中,默认的错误处理很简单.一条错误消息会被发送到浏览器,这条消息带有文件名.行号以及描述错误的消息. PHP 错误处理 在创建脚本和 Web 应用程序时,错误处理是一个重 ...
- JavaScript 客户端JavaScript之 脚本化浏览器窗口
1.计时器 客户端Javascript以全局函数setTimeOut().clearTimeOut().setInterval().clearInterval()提供这一功能. 前者是从运行的那一 ...