LCT的各种操作。。。

cut link add mul size rev query

写的效率不够高。。。

BZOJ上似乎TLE。

。。。

A1303. tree(伍一鸣)
时间限制:2.5s   内存限制:64.0MB  
总提交次数:727   AC次数:238  
平均分:45.59
将本题分享到:
      
试题来源
  2012中国国家集训队命题答辩
问题描写叙述
  一棵n个点的树。每一个点的初始权值为1。

对于这棵树有q个操作,每一个操作为下面四种操作之中的一个:

  + u v c:将u到v的路径上的点的权值都加上自然数c。

  - u1 v1 u2 v2:将树中原有的边(u1,v1)删除,增加一条新边(u2,v2)。保证操作完之后仍然是一棵树;

  * u v c:将u到v的路径上的点的权值都乘上自然数c;

  / u v:询问u到v的路径上的点的权值和。求出答案对于51061的余数。

输入格式
  第一行两个整数n,q

  接下来n-1行每行两个正整数u。v,描写叙述这棵树

  接下来q行,每行描写叙述一个操作
输出格式
  对于每一个/相应的答案输出一行
例子输入
3 2

1 2

2 3

* 1 3 4

/ 1 1
例子输出
4
数据规模和约定
  10%的数据保证,1<=n,q<=2000

  另外15%的数据保证。1<=n。q<=5*10^4,没有-操作,而且初始树为一条链

  另外35%的数据保证,1<=n,q<=5*10^4。没有-操作

  100%的数据保证,1<=n,q<=10^5,0<=c<=10^4

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int maxn=100100;
const LL mod=51061;
int ch[maxn][2],pre[maxn];
bool rev[maxn],rt[maxn];
LL size[maxn],key[maxn],add[maxn],mul[maxn],sum[maxn];
void update_add(int r,LL d)
{
if(!r) return ;
if(d==0) return ;
key[r]=(key[r]+d)%mod;
add[r]=(add[r]+d)%mod;
sum[r]=(size[r]*d+sum[r])%mod;
}
void update_mul(int r,LL d)
{
if(!r) return ;
if(d==1) return ;
sum[r]=(sum[r]*d)%mod;
key[r]=(key[r]*d)%mod;
mul[r]=(mul[r]*d)%mod;
add[r]=(add[r]*d)%mod;
}
void update_rev(int r)
{
if(!r) return ;
swap(ch[r][0],ch[r][1]);
rev[r]=rev[r]^1;
}
void push_down(int r)
{
if(!r) return ;
if(rev[r])
{
if(ch[r][0]) update_rev(ch[r][0]);
if(ch[r][1]) update_rev(ch[r][1]);
rev[r]=0;
}
if(mul[r]!=1)
{
if(ch[r][0]) update_mul(ch[r][0],mul[r]);
if(ch[r][1]) update_mul(ch[r][1],mul[r]);
mul[r]=1;
}
if(add[r])
{
if(ch[r][0]) update_add(ch[r][0],add[r]);
if(ch[r][1]) update_add(ch[r][1],add[r]);
add[r]=0;
}
}
void push_up(int r)
{
sum[r]=key[r]%mod;
size[r]=1;
if(ch[r][0])
{
sum[r]=(sum[r]+sum[ch[r][0]])%mod;
size[r]+=size[ch[r][0]];
}
if(ch[r][1])
{
sum[r]=(sum[r]+sum[ch[r][1]])%mod;
size[r]+=size[ch[r][1]];
}
}
void Rotate(int x)
{
int y=pre[x],kind=ch[y][1]==x;
ch[y][kind]=ch[x][!kind];
pre[ch[y][kind]]=y;
pre[x]=pre[y];
pre[y]=x;
ch[x][!kind]=y;
if(rt[y]) rt[y]=false,rt[x]=true;
else ch[pre[x]][ch[pre[x]][1]==y]=x;
push_up(y);
}
void P(int r)
{
if(!rt[r]) P(pre[r]);
push_down(r);
}
void Splay(int r)
{
P(r);
while(!rt[r])
{
int f=pre[r],ff=pre[f];
if(rt[f]) Rotate(r);
else if((ch[ff][1]==f)==(ch[f][1]==r)) Rotate(f),Rotate(r);
else Rotate(r),Rotate(r);
}
push_up(r);
}
int Access(int x)
{
int y=0;
for(;x;x=pre[y=x])
{
Splay(x);
rt[ch[x][1]]=true; rt[ch[x][1]=y]=false;
push_up(x);
}
return y;
}
void mroot(int r)
{
Access(r);
Splay(r);
update_rev(r);
}
void link(int u,int v)
{
mroot(u);
pre[u]=v;
}
void cut(int u,int v)
{
mroot(u);
Splay(v);
pre[ch[v][0]]=pre[v];
pre[v]=0;
rt[ch[v][0]]=true;
ch[v][0]=0;
push_up(v);
}
void Add(int u,int v,LL d)
{
mroot(u);
Access(v);
Splay(v);
update_add(v,d);
}
void Mul(int u,int v,LL d)
{
mroot(u);
Access(v);
Splay(v);
update_mul(v,d);
}
void debug();
void query(int u,int v)
{
mroot(u);
Access(v);
Splay(v);
//cout<<"size: "<<size[v]<<" sum: "<<sum[v]<<endl;
printf("%lld\n",sum[v]);
}
struct Edge
{
int to,next;
}edge[maxn*2];
int Adj[maxn],Size; void add_edge(int u,int v)
{
edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++;
}
int n,q;
void init()
{
Size=0;
for(int i=0;i<=n+10;i++)
{
Adj[i]=-1;
ch[i][0]=ch[i][1]=0;
pre[i]=0; rt[i]=true; rev[i]=false;
key[i]=1; size[i]=1; add[i]=0; mul[i]=1; sum[i]=1;
}
}
void dfs(int u)
{
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(pre[v]!=0) continue;
pre[v]=u;
dfs(v);
}
}
void showit(int x)
{
if(x)
{
push_down(x);
showit(ch[x][0]);
printf("结点: %2d 左儿子: %2d 右儿子: %2d 父结点: %2d size: %2lld sum: %2lld key: %2lld\n",
x,ch[x][0],ch[x][1],pre[x],size[x],sum[x],key[x]);
showit(ch[x][1]);
}
}
void debug()
{
for(int i=0;i<=n;i++)
{
if(rt[i])
{
cout<<"ROOT: "<<i<<endl;
showit(i);
cout<<"..........\n";
}
}
}
int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
init();
for(int i=0;i<n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v); add_edge(v,u);
}
pre[1]=-1; dfs(1); pre[1]=0;
//debug();
char op[10];
while(q--)
{
scanf("%s",op);
if(op[0]=='+')
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
Add(u,v,c);
}
else if(op[0]=='-')
{
int u1,v1,u2,v2;
scanf("%d%d%d%d",&u1,&v1,&u2,&v2);
cut(u1,v1);
link(u2,v2);
}
else if(op[0]=='*')
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
Mul(u,v,c);
}
else if(op[0]=='/')
{
int u,v;
scanf("%d%d",&u,&v);
query(u,v);
}
//debug();
}
}
return 0;
}

Tsinsen A1303. tree(伍一鸣) LCT的更多相关文章

  1. Tsinsen A1303. tree(伍一鸣) (LCT+处理标记)

    [题目链接] http://www.tsinsen.com/A1303 [题意] 给定一棵树,提供树上路径乘/加一个数,加边断边,查询路径和的操作. [思路] LCT+传标 一次dfs构造LCT. L ...

  2. 【国家集训队2012】tree(伍一鸣)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一:  + u v c:将u到v的路径上的点的权值都加上自然数c:  - u1 v1 u2 ...

  3. [COGS 1799][国家集训队2012]tree(伍一鸣)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...

  4. cogs1799 [国家集训队2012]tree(伍一鸣)

    LCT裸题 注意打标记之间的影响就是了 这个膜数不会爆unsigned int #include<cstdio> #include<cstdlib> #include<a ...

  5. 数据结构(动态树):[国家集训队2012]tree(伍一鸣)

    [问题描述] 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原 ...

  6. BZOJ2631 tree(伍一鸣) LCT 秘制标记

    这个题一看就是裸地LCT嘛,但是我wa了好几遍,这秘制标记...... 注意事项:I.*对+有贡献 II.先下传*再下传+(因为我们已经维护了+,不能再让*对+产生贡献)III.维护+用到size # ...

  7. HDU 5002 Tree(动态树LCT)(2014 ACM/ICPC Asia Regional Anshan Online)

    Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node ...

  8. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  9. HDU 4718 The LCIS on the Tree (动态树LCT)

    The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Oth ...

随机推荐

  1. TCP的可靠传输(依赖流量控制、拥塞控制、连续ARQ)

    TCP可靠性表现在它向应用层提供的数据是无差错,有序,无丢失,即递交的和发送的数据是一样的. 可靠性依赖于流量控制.拥塞控制.连续ARQ等技术 <TCP/IP详解>中的“分组”是不是就是报 ...

  2. 洛谷——P1886 滑动窗口|| POJ——T2823 Sliding Window

    https://www.luogu.org/problem/show?pid=1886#sub || http://poj.org/problem?id=2823 题目描述 现在有一堆数字共N个数字( ...

  3. HDOJ 5294 Tricks Device 最短路(记录路径)+最小割

    最短路记录路径,同一时候求出最短的路径上最少要有多少条边, 然后用在最短路上的边又一次构图后求最小割. Tricks Device Time Limit: 2000/1000 MS (Java/Oth ...

  4. nodeJS npm grunt grunt-cli

    1.安装好nodeJS后 ,一般都会把npm也安装好的.nodeJs集成npm的,可通过在cmd 分别运行 node -v和 npm -v来查看他们的版本,假设显示可说明可继续以下的操作 2.想安装g ...

  5. python微框架Bottle(http)

    环境: win7系统 Python2.7 一 背景和概述 眼下项目中须要加入一个激活码功能,打算单独弄一个httpserver来写. 由于之前的游戏中已经有了一套完整的激活码生成工具和验证httpse ...

  6. Linux 设备文件的创建和mdev

    引子 本文是嵌入式企鹅圈开篇--<linux字符设备驱动剖析>的姐妹篇,在上述文章里面我们具体描写叙述了字符设备驱动框架涉及的驱动注冊.通过设备文件来訪问驱动等知识.并明白通过device ...

  7. tf.placeholder类似函数中的形参

    tf.placeholder(dtype, shape=None, name=None) 此函数可以理解为形参,用于定义过程,在执行的时候再赋具体的值 参数: dtype:数据类型.常用的是tf.fl ...

  8. nyoj--301--递推求值(经典矩阵运算)

    递推求值 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给你一个递推公式: f(x)=a*f(x-2)+b*f(x-1)+c 并给你f(1),f(2)的值,请求出f(n ...

  9. SPOJ 694/705 后缀数组

    思路: 论文题*n Σn-i-ht[i]+1 就是结果 O(n)搞定~ //By SiriusRen #include <cstdio> #include <cstring> ...

  10. Excel中将字符串中从右起第n个指定字符替换的方法

    比如你想把www.baidu.com.cn中的倒数第二个”.”替换成@,则可以用: =SUBSTITUTE(A1,".","@",LEN(A1)-LEN(SUB ...