杜教的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 ...
随机推荐
- sql server 扩展存储过程
C# 代码 using Microsoft.SqlServer.Server; using System; using System.Collections.Generic; using System ...
- 浅析Linux系统下用户与权限管理
Linux作为一种多用户多任务操作系统,在日常的使用中不可避免地要划分出一个角色的概念来管理和使用计算机,这个角色与每一个计算机使用者关联,在Linux中称这种角色为用户.而在每一个用户使用计算机的过 ...
- Android实现后台长期监听时间变化
1.首先我们的目的是长期监听时间变化,事实上应用程序退出. 通过了解我们知道注冊ACTION_TIME_TICK广播接收器能够监听系统事件改变,可是 查看SDK发现ACTION_TIME_TICK广播 ...
- Html5新特性 <canvas>画板画直线
以下样例为用canvas标签画多条直线 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...
- LSPCI具体解释分析
一.PCI简单介绍 PCI是一种外设总线规范.我们先来看一下什么是总线:总线是一种传输信号的路径或信道.典型情况是,总线是连接于一个或多个导体的电气连线,总 线上连接的全部设备可在同一时间收到 ...
- TinyXml快速入门(二)
在<TinyXml快速入门(一)>中我介绍了使用TinyXml库如何创建和打印xml文件,下面我介绍使用tinyxml库对xml文件进行一系列的操作,包括获取xml文件声明,查询指定节点. ...
- GCC编译选项
一.看例子分析gcc 的编译选项 gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld 1.-I /home/h ...
- 搭建HWI(HiveWebInterface)步骤总结
众所周知,Hive有三种使用方式:CLI.HWI浏览器.Thrift客户端.安装配置完Hive后无需进行额外操作即可使用CLI.但是HWI则需要单独搭建.本文主要记录我自己搭建HWI的过程. 说明:本 ...
- Android - Service启动机制
以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删):http://blog.csdn.net/luoshe ...
- 在winform程序中实现按照不同的角色或用户展现不同的页面
SqlConnection cn = new SqlConnection(); cn.ConnectionString = "Data Source=192.168. ...