王学长的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位 ...
随机推荐
- [置顶] Hash查找,散列查找
//Hash.h #ifndef HASH_H #define HASH_H #define HASH_ARR_SIZE 100 #define FILL -1 #include <stdlib ...
- BaseAdapter的ArrayIndexOutOfBoundsException
最近写一个listView中多个listItem布局时,convertView缓存及使用,类似微信的聊天界面的listView,报了一个异常: 11-25 15:51:49.076: E/InputE ...
- [Javascript] Advanced Reduce: Additional Reducer Arguments
Sometimes we need to turn arrays into new values in ways that can't be done purely by passing an acc ...
- 非对称加密算法RSA--转
RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作,也很流行.算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和L ...
- 404 Not Find When using Owin with OAuth
在使用Owin+OAuth时,一步一步的测试时,在用 OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = ...
- Asp.net 回车默认按钮
<head> <script type="text/javascript"> function OnKey() { if (ev ...
- python 下的数据结构与算法---7:查找
一:线性查找(Sequential Search) 线性查找可以说是我们用的最早也会是用的最多的查找方式了.其对应的是线性数据结构,回顾一下线性数据结构,其特点是先后加入的元素是有顺序的,相邻的.而线 ...
- Lesson 6: Exploring the World of Typefaces
Lesson 6: Exploring the World of Typefaces 这课提到的字体都是 英文 的. Article 1: More Google Web Fonts That Don ...
- ssh key报but this does not map back to the address – POSSIBLE BREAK-IN ATTEMPT!错误
在/etc/hosts 文件加上对方的主机名 ip地址,可以ping通主机名即可.
- MyEclipse汉化后问题
今天为了教学生如何汉化MyEclipse10.7,所以讲IDE汉化了一下. 个人还是喜欢用英文版,所以就将D:\MyEclipse\MyEclipse 10目录下的配置文件myeclipse.ini里 ...