LCT

  又一道名字叫做Tree的题目……

  看到删边加边什么的……又是动态树问题……果断再次搬出LCT。

  这题比起上道【3282】tree的难点在于需要像线段树维护区间那样,进行树上路径的权值修改&查询。那么类似的,我们就可以在splay的每个节点上记录一坨信息了……

个人感觉跟线段树标记不一样的地方:

  1.标记只是给儿子们用的,打标记的节点本身在打标记的同时就修改了信息了,然后在Push_down的时候直接放下去……(没法在push_down的时候更新自己,要不mul标记怎么改?)

  2.虽然splay是按深度为关键字排序的,但是我们对整条路径操作的时候只要把一个端点上打了标记并且修改了就行了……(当然这个节点必须是“树根”)不用在意顺序……反正都加了就对了= =

虽然不是很明白为什么这样打标记就是对的,在更改树的样子的时候也不会变……但是隐隐地感觉这样是可行的,而且也对了= =就这样姑且记下来好了

另外,学习了另外一位大神的LCT模板,好像会快一些……?

 /**************************************************************
Problem: 2631
User: Tunix
Language: C++
Result: Accepted
Time:14720 ms
Memory:5724 kb
****************************************************************/ //BZOJ 2631
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
const int N=,MOD=;
//#define debug
void read(int &v){
v=;
int sign=; char ch=getchar();
while(ch<'' || ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>='' && ch<=''){v=v*+ch-''; ch=getchar();}
v*=sign;
}
//template of link-cut-tree for NOI2014 magic foreast int fa[N],c[N][],size[N],n,m;
unsigned int val[N],mul[N],add[N],sum[N];
bool rev[N];
#define L c[x][0]
#define R c[x][1]
/*
void Push_up(int x){
mid[x]=val[mid[c[x][0]]]>val[mid[c[x][1]]] ? mid[c[x][0]] : mid[c[x][1]] ,
val[mid[x]]< val[x] ? mid[x]=x : 1;
}
*/
void Push_up(int x){
sum[x]=val[x]; size[x]=;
L ? sum[x]=(sum[x]+sum[L]) % MOD,
size[x]+=size[L] : ;
R ? sum[x]=(sum[x]+sum[R]) % MOD,
size[x]+=size[R] : ;
}
inline void update(int x,int mu,int ad){
val[x]=(val[x]*mu+ad) % MOD;
sum[x]=(sum[x]*mu+ad*size[x]) %MOD;
mul[x]=(mul[x]*mu) % MOD;
add[x]=(add[x]*mu+ad) % MOD;
}
int swap_tmp=;
void Push_down(int x){
rev[x] ? rev[x]=,rev[L]^=,rev[R]^=,swap_tmp=L,L=R,R=swap_tmp : ;
if(mul[x]!= || add[x]!=) update(L,mul[x],add[x]),update(R,mul[x],add[x]),mul[x]=,add[x]= ;
}
bool not_root(int x){
return c[fa[x]][]==x || c[fa[x]][]==x;
}
void rotate(int x){
int y=fa[x],p=c[y][]==x;
fa[x]=fa[y], not_root(y) ? c[fa[y]][ c[fa[y]][]==y ]=x:,
(c[y][p]=c[x][!p]) ? fa[c[y][p]]=y : ,
Push_up(c[ fa[y]=x ][!p]=y);
}
void preview(int x){
if (not_root(x)) preview(fa[x]);
Push_down(x);
}//从根到x全部Push_down一遍
void splay(int x,int y=){
for(preview(x);not_root(x);rotate(x))
not_root(y=fa[x]) ? rotate( (c[y][]==x^c[fa[y]][]==y ? x : y)), : ;
Push_up(x);
}
void access(int x,int las=){
for(;x;splay(x),c[x][]=las,las=x,x=fa[x]);
}
void makeroot(int x){
access(x),splay(x),rev[x]^=;
}
int find(int x){
access(x),splay(x);
while(c[x][]) x=c[x][];
return x;
}
void link(int x,int y){
makeroot(x),fa[x]=y;
}
void cut(int x,int y){
makeroot(x),access(y),splay(y);
if (c[y][]==x) c[y][]=fa[x]=;
}
void update_add(int x,int y,int v){
makeroot(x),access(y),splay(y),add[y]=(add[y]+v)%MOD,val[y]=(val[y]+v)%MOD;
}
void update_mul(int x,int y,int v){
makeroot(x),access(y),splay(y),mul[y]=(mul[y]*v)%MOD,val[y]=(val[y]*v)%MOD,add[y]=add[y]*v%MOD;
}
void query(int x,int y){
makeroot(x),access(y),splay(y);
printf("%d\n",sum[y]);
}
/*
int query(int x,int y){
return makeroot(x),access(y),splay(y),mid[y];
}
*/
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif
read(n); read(m);
F(i,,n) add[i]=,val[i]=mul[i]=sum[i]=size[i]=;
int x,y,v;
F(i,,n){
read(x); read(y);
link(x,y);
}
char cmd[];
F(i,,m){
scanf("%s",cmd);
read(x),read(y);
switch(cmd[]){
case '+': read(v),update_add(x,y,v);break;
case '-': cut(x,y); read(x),read(y); link(x,y);break;
case '*': read(v),update_mul(x,y,v); break;
case '/': query(x,y);break;
}
#ifdef debug
printf("i=%d\n",i);
F(x,,n) printf("%d %d %d %d %d %d %d\n",fa[x],L,R,sum[x],val[x],mul[x],add[x]);
#endif
}
return ;
}

【BZOJ】【2631】Tree的更多相关文章

  1. 【Bzoj 1835 基站选址】

    基站选址的区间里隐藏着DP优化的机密…… 分析:       不论是做过乘积最大还是石子合并,或者是其他的入门级别的区间DP题目的人呐,大米并认为读题后就能够轻松得出一个简洁明了的Dp转移方程.    ...

  2. 【BZOJ 2744 朋友圈】

    Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1570  Solved: 532[Submit][Status][Discuss] Descripti ...

  3. 【BZOJ 5038 不打兔子】

    Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 22  Solved: 8[Submit][Status][Discuss] Description 勤 ...

  4. 【BZOJ 1088 扫雷Mine】模拟

    http://www.lydsy.com/JudgeOnline/problem.php?id=1088 2*N的扫雷棋盘,第二列的值a[i]记录第 i 个格子和它8连通的格子里面雷的数目. 第一列的 ...

  5. 【BZOJ做题记录】07.07~?

    在NOI一周前重开一个坑 最后更新时间:7.08 07:38 7.06 下午做的几道CQOI题: BZOJ1257: [CQOI2007]余数之和sum:把k mod i写成k-k/i*i然后分段求后 ...

  6. 【bzoj5050】【bzoj九月月赛H】建造摩天楼

    讲个笑话,这个题很休闲的. 大概是这样的,昨天看到这个题,第一眼星际把题目看反了然后感觉这是个傻逼题. 后来发现不对,这个修改一次的影响是很多的,可能导致一个数突然可以被改,也可能导致一个数不能被改. ...

  7. 【BZOJ 4151 The Cave】

    Time Limit: 5 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 293  Solved: 144[Submit][Status][Di ...

  8. 【BZOJ 2458 最小三角形】

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1551  Solved: 549[Submit][Status][Discuss] Descripti ...

  9. 【BZOJ 5000 OI树】

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 107  Solved: 64[Submit][Status][Discuss] Description ...

  10. 【BZOJ 5047 空间传送装置】

    Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 282  Solved: 121[Submit][Status][Discuss] Descriptio ...

随机推荐

  1. PHP面向对象之旅:static变量与方法

    static关键字声明一个属性或方法是和类相关的,而不是和类的某个特定的实例相关,因此,这类属性或方法也称为“类属性”或“类方法”. 如果访问控制权限允许,可不必创建该类对象而直接使用类名加两个冒号“ ...

  2. C++求斐波那契数

    题目内容:斐波那契数定义为:f(0)=0,f(1)=1,f(n)=f(n-1)+f(n-2)(n>1且n为整数) 如果写出菲氏数列,则应该是: 0 1 1 2 3 5 8 13 21 34 …… ...

  3. AsyncTask的简单使用

    package com.zzw.life; import android.app.Activity; import android.os.AsyncTask; import android.os.Bu ...

  4. 网页绘制图表 Google Charts with JavaScript #2 ....与ASP.NET网页结合 (ClientScriptManager.RegisterStartupScript 方法)

    此为文章备份,原文出处(我的网站) 网页绘制图表 Google Charts with JavaScript #2 ....与ASP.NET网页结合 (ClientScriptManager.Regi ...

  5. jquery mobile最棘手的一个问题

    大多数jquery mobile开发的妹子们都碰到过这个问题: 如何调用loading效果   这里给出一段代码,赶紧练手吧. //显示loading function showLoading(){ ...

  6. EMVTag系列1《数据分组》

    数据分组的设计在个人化过程中承担着重要的作用.数据分组标识符(DGI)是两字节十六进制数.数据分组标识的第一个字节等于'01'到'1E',表明数据存储的SFI.第二个字节表明SFI记录的记录编号.其他 ...

  7. DB2行转列(多维度)

    多维度下进行行列转换,下面的行列转换时根据客户,所属银行机构进行的行列转换. -----------------建表 CREATE TABLE CUST_BANK_INFO ( CUST_ID ), ...

  8. 关于EF分页查询报错(Count must have a non-negative value.)的解决方案

    具体的异常信息如下,一开始没有写日志只看到错误信息:Count must have a non-negative value.,从表面意思可以看出来是Count值出现了负数,所以报错,查了半天的原因也 ...

  9. ANT编译build.xml

    一,体验ant就像每个语言都有HelloWorld一样,一个最简单的应用能让人感受一下Ant1,首先你要知道你要干什么,我现在想做的事情是:编写一些程序编译它们把它打包成jar包把他们放在应该放置的地 ...

  10. hdu 2094 产生冠军

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2094 产生冠军 Description 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比 ...