杜教的AAA树
膜膜膜,常数挺小的。。。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
const int maxn=1e5+,inf=-1u>>;
int getint(){
int res=,f=;char c=getchar();
while(!isdigit(c))f=f==-||c=='-'?-:,c=getchar();
while(isdigit(c))res=res*+c-'',c=getchar();
return res*f;
}
int n,m;
struct info{
int mx,mn,sum,siz;
info(){}
info(int mx,int mn,int sum,int siz):
mx(mx),mn(mn),sum(sum),siz(siz){}
};
struct flag{
int mul,add;
flag(){mul=;}
flag(int mul,int add):
mul(mul),add(add){}
bool empty(){return mul==&&add==;}
};
info operator+(const info &a,const flag &b) {
return a.siz?info(a.mx*b.mul+b.add,a.mn*b.mul+b.add,a.sum*b.mul+b.add*a.siz,a.siz):a;
}
info operator+(const info &a,const info &b) {
return info(max(a.mx,b.mx),min(a.mn,b.mn),a.sum+b.sum,a.siz+b.siz);
}
flag operator+(const flag &a,const flag &b) {
return flag(a.mul*b.mul,a.add*b.mul+b.add);
}
struct node{
node *ch[],*f;
flag Cha,All;
info cha,sub,all;
bool rev,inr;
int val;
void revt(){rev^=;swap(ch[],ch[]);}
void makec(const flag &a){
Cha=Cha+a;cha=cha+a;val=val*a.mul+a.add;
all=cha+sub;
}
void makes(const flag &a,bool _=){
All=All+a;all=all+a;sub=sub+a;
if(_)makec(a);
}
void update(){
cha=all=sub=info(-inf,inf,,);
if(!inr)all=cha=info(val,val,val,);
rep(i,,)if(ch[i])cha=cha+ch[i]->cha,sub=sub+ch[i]->sub;
rep(i,,)if(ch[i])all=all+ch[i]->all;
rep(i,,)if(ch[i])sub=sub+ch[i]->all;
}
void down(){
if(rev){
if(ch[])ch[]->revt();
if(ch[])ch[]->revt();
rev=;
}
if(!All.empty()){
rep(i,,)if(ch[i])ch[i]->makes(All,i>=);
All=flag(,);
}
if(!Cha.empty()){
rep(i,,)if(ch[i])ch[i]->makec(Cha);
Cha=flag(,);
}
}
node *C(int i){if(ch[i])ch[i]->down();return ch[i];}
bool d(int ty){return f->ch[ty+]==this;}
int D(){rep(i,,)if(f->ch[i]==this)return i;}
void sets(node *x,int d){if(x)x->f=this;ch[d]=x;}
bool rt(int ty){
if(ty==)return !f||(f->ch[]!=this&&f->ch[]!=this);
else return !f||!f->inr||!inr;
}
}nd[maxn*],*cur=nd+maxn,*pool[maxn],**Cur=pool;
int _cnt;
node *newnode(){
_cnt++;
node *x=(Cur==pool)?cur++:*(--Cur);
rep(i,,)x->ch[i]=;x->f=;
x->All=x->Cha=flag(,);
x->all=x->cha=info(-inf,inf,,);
x->inr=;x->rev=;x->val=;
return x;
}
void dele(node *x){*(Cur++)=x;}
void rot(node *x,int ty){
node *p=x->f;int d=x->d(ty);
if(!p->f)x->f=;else p->f->sets(x,p->D());
p->sets(x->ch[!d+ty],d+ty);x->sets(p,!d+ty);p->update();
}
void splay(node *x,int ty=){
while(!x->rt(ty)){
if(x->f->rt(ty))rot(x,ty);
else if(x->d(ty)==x->f->d(ty))rot(x->f,ty),rot(x,ty);
else rot(x,ty),rot(x,ty);
}x->update();
}
void add(node *u,node *w){
w->down();
rep(i,,)if(!w->ch[i]){w->sets(u,i);return;}
node *x=newnode(),*v;
for(v=w;v->ch[]->inr;v=v->C());
x->sets(v->ch[],);x->sets(u,);
v->sets(x,);splay(x,);
}
void del(node *w){
if(w->f->inr){
w->f->f->sets(w->f->ch[-w->D()],w->f->D());
dele(w->f);splay(w->f->f,);
}else w->f->sets(,w->D());
w->f=;
}
void access(node *w){
static node *sta[maxn];
static int top=;
node *v=w,*u;
for(u=w;u;u=u->f)sta[top++]=u;
while(top)sta[--top]->down();
splay(w);
if(w->ch[])u=w->ch[],w->ch[]=,add(u,w),w->update();
while(w->f){
for(u=w->f;u->inr;u=u->f);
splay(u);
if(u->ch[])w->f->sets(u->ch[],w->D()),splay(w->f,);
else del(w);
u->sets(w,);
(w=u)->update();
}splay(v);
}
void makert(node *x){
access(x);x->revt();
}
node *findp(node *u){
access(u);u=u->C();
while(u&&u->ch[])u=u->C();
return u;
}
node *findr(node *u){for(;u->f;u=u->f);return u;}
node* cut(node *u){
node *v=findp(u);
if(v)access(v),del(u),v->update();
return v;
}
void link(node *u,node *v) {
node* p=cut(u);
if(findr(u)!=findr(v))p=v;
if(p)access(p),add(u,p),p->update();
}
int main(){
n=getint();m=getint();
static int _u[maxn],_v[maxn];
rep(i,,n)_u[i]=getint(),_v[i]=getint();
rep(i,,n+){
nd[i].val=getint();
nd[i].update();
}
rep(i,,n)makert(nd+_u[i]),link(nd+_u[i],nd+_v[i]);
int root=getint();
makert(nd+root);
int x,y,z;
node *u,*v;
while(m--){
int k=getint();x=getint();
u=nd+x;
if(k==||k==||k==||k==||k==){
access(u);
if(k==||k==||k==){
int ans=u->val;
rep(i,,)if(u->ch[i]){
info res=u->ch[i]->all;
if(k==) ans=min(ans,res.mn);
else if(k==) ans=max(ans,res.mx);
else if(k==) ans+=res.sum;
}printf("%d\n",ans);
}else{
y=getint();
flag fg(k==,y);
u->val=u->val*fg.mul+fg.add;
rep(i,,)if(u->ch[i])u->ch[i]->makes(fg);
u->update();
}
}else if(k==||k==||k==||k==||k==){
y=getint();
makert(u),access(nd+y),splay(u);
if (k==||k==||k==) {
info ans=u->cha;
if (k==) printf("%d\n",ans.mn);
else if (k==) printf("%d\n",ans.mx);
else printf("%d\n",ans.sum);
}else u->makec(flag(k==,getint()));
makert(nd+root);
}else if(k==)link(u,nd+getint());
else if(k==)makert(u),root=x;
}
return ;
}
杜教的AAA树的更多相关文章
- Mobius 反演与杜教筛
积性函数 积性函数 指对于所有互质的整数 aaa 和 bbb 有性质 f(ab)=f(a)f(b)f(ab)=f(a)f(b)f(ab)=f(a)f(b) 的数论函数. 特别地,若所有的整数 aaa ...
- 王学长的AAA树
让我们响应王学长的号召勇敢的分开写splay和lct吧! 分开写大法好!!!!!!!!!!!杜教的ch[4]弱爆了!!!! #include <stdio.h> #include < ...
- 51nod 1244 莫比乌斯函数之和(杜教筛)
[题目链接] http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 [题目大意] 计算莫比乌斯函数的区段和 [题解] 利 ...
- 51nod 1237 最大公约数之和 V3(杜教筛)
[题目链接] https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1237 [题目大意] 求[1,n][1,n]最大公约数之和 ...
- 杜教筛 && bzoj3944 Sum
Description Input 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用空格分隔的数ans1,ans ...
- 51NOD 1220 约数之和 [杜教筛]
1220 约数之和 题意:求\(\sum_{i=1}^n \sum_{j=1}^n \sigma_1(ij)\) \[ \sigma_0(ij) = \sum_{x\mid i}\sum_{y\mi ...
- BZOJ 4176: Lucas的数论 [杜教筛]
4176: Lucas的数论 题意:求\(\sum_{i=1}^n \sum_{j=1}^n \sigma_0(ij)\) \(n \le 10^9\) 代入\(\sigma_0(nm)=\sum_{ ...
- 51NOD 1222 最小公倍数计数 [莫比乌斯反演 杜教筛]
1222 最小公倍数计数 题意:求有多少数对\((a,b):a<b\)满足\(lcm(a,b) \in [1, n]\) \(n \le 10^{11}\) 卡内存! 枚举\(gcd, \fra ...
- 51NOD 1237 最大公约数之和 V3 [杜教筛]
1237 最大公约数之和 V3 题意:求\(\sum_{i=1}^n\sum_{j=1}^n(i,j)\) 令\(A(n)=\sum_{i=1}^n(n,i) = \sum_{d\mid n}d \c ...
随机推荐
- C语言单元測试
C语言单元測试 对于敏捷开发来说,单元測试不可缺少,对于Java开发来说,JUnit非常好,对于C++开发,也有CPPUnit可供使用,而对于传统的C语言开发,就没有非常好的工具可供使用,能够找到的有 ...
- [AngularJS] Using $parse Service
$parse is useful when you want to parse an expression and the context is not defined yet. For exampl ...
- Linux下查看所有用户(shell脚本获取)
在Linux系统中,使用者账号管理最重要的两个文件是/etc/password和/etc/shadow.在/etc/password文件中,每一行都代表一个账号,但是有很多账号是系统账号.比如:b ...
- Configuring Network Configuration-RHEL7
1.查看网络状态systemctl status NetworkManager You can use the systemctl status NetworkManager command to ...
- 【转】iOS实时卡顿监控
转自http://www.tanhao.me/code/151113.html/ 在移动设备上开发软件,性能一直是我们最为关心的话题之一,我们作为程序员除了需要努力提高代码质量之外,及时发现和监控软件 ...
- 初识web01
Tomcat 服务器 B/S 浏览器/服务器 C/S 客户端/服务器 URI:统一资源标识符 大 广 /项目名 URL:统一资源定位符 ...
- jQuery事件与动画
一 事件 1 加载DOM事件 $(document).ready():执行时机:DOM元素准备就绪 执行次数:多次 简单写法:原:$(document).ready(function(){}) ...
- 为什么不使用frame框架的原因
框架的优点 重载页面时不需要重载整个页面,只需要重载页面中的一个框架页(减少了数据的传输,增加了网页下载速度) 方便制作导航栏 框架的缺点 会产生很多页面,不容易管理 不容易打印 浏览器的后退按钮无效 ...
- javascript !!的作用是把一个其他类型的变量转成的bool类型
!!的作用是把一个其他类型的变量转成的bool类型
- C++线性序列容器<vector>简单总结
C++线性序列容器<vector>简单总结 vector是一个长度可变的数组,使用的时候无须声明上限,随着元素的增加,Vector的长度会自动增加:Vector类提供额外的方法来增加.删除 ...