Description
一棵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的余数。

Input
第一行两个整数n,q 
接下来n-1行每行两个正整数u,v,描述这棵树 
接下来q行,每行描述一个操作

Output
对于每个/对应的答案输出一行

Sample Input
3 2 
1 2 
2 3 
* 1 3 4 
/ 1 1

Sample Output
4

Hint
数据规模: 
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

正解:link-cut tree。

毒瘤数据结构题,调了我一下午。。主要是加和乘的lazy标记,下放时如果是乘,那么加的那个标记也要同乘,并且要先下放乘的标记,再下放加的标记。

  1. //It is made by wfj_2048~
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <cstdlib>
  6. #include <cstdio>
  7. #include <vector>
  8. #include <cmath>
  9. #include <queue>
  10. #include <stack>
  11. #include <map>
  12. #include <set>
  13. #define inf (1<<30)
  14. #define r64 (51061)
  15. #define N (100010)
  16. #define il inline
  17. #define RG register
  18. #define uint unsigned int
  19. #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
  20.  
  21. using namespace std;
  22.  
  23. uint ch[N][],fa[N],size[N],lazy[N],st[N],rev1[N],rev2[N],val[N],sum[N],n,q;
  24. char s[];
  25.  
  26. il uint gi(){
  27. RG uint x=,q=; RG char ch=getchar(); while ((ch<'' || ch>'') && ch!='-') ch=getchar();
  28. if (ch=='-') q=-,ch=getchar(); while (ch>='' && ch<='') x=x*+ch-,ch=getchar(); return q*x;
  29. }
  30.  
  31. il void pushdown(RG uint x){
  32. RG uint &l=ch[x][],&r=ch[x][];
  33. if (lazy[x]) lazy[x]=,lazy[l]^=,lazy[r]^=,swap(l,r);
  34. if (rev2[x]!=){
  35. (val[l]*=rev2[x])%=r64,(val[r]*=rev2[x])%=r64;
  36. (sum[l]*=rev2[x])%=r64,(sum[r]*=rev2[x])%=r64;
  37. (rev1[l]*=rev2[x])%=r64,(rev1[r]*=rev2[x])%=r64;
  38. (rev2[l]*=rev2[x])%=r64,(rev2[r]*=rev2[x])%=r64,rev2[x]=;
  39. }
  40. if (rev1[x]){
  41. (val[l]+=rev1[x])%=r64,(val[r]+=rev1[x])%=r64;
  42. (sum[l]+=rev1[x]*(size[l]%r64))%=r64,(sum[r]+=rev1[x]*(size[r]%r64))%=r64;
  43. (rev1[l]+=rev1[x])%=r64,(rev1[r]+=rev1[x])%=r64,rev1[x]=;
  44. }
  45. return;
  46. }
  47.  
  48. il void pushup(RG uint x){
  49. sum[x]=(sum[ch[x][]]+sum[ch[x][]]+val[x])%r64;
  50. size[x]=size[ch[x][]]+size[ch[x][]]+; return;
  51. }
  52.  
  53. il uint isroot(RG uint x){ return ch[fa[x]][]!=x && ch[fa[x]][]!=x; }
  54.  
  55. il void rotate(RG uint x){
  56. RG uint y=fa[x],z=fa[y],k=ch[y][]==x; if (!isroot(y)) ch[z][ch[z][]==y]=x; fa[x]=z;
  57. ch[y][k^]=ch[x][k],fa[ch[x][k]]=y,ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return;
  58. }
  59.  
  60. il void splay(RG uint x){
  61. RG uint top=; st[++top]=x;
  62. for (RG uint i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
  63. while (top) pushdown(st[top--]);
  64. while (!isroot(x)){
  65. RG uint y=fa[x],z=fa[y];
  66. if (!isroot(y)){ if ((ch[z][]==y)^(ch[y][]==x)) rotate(x); else rotate(y); }
  67. rotate(x);
  68. }
  69. return;
  70. }
  71.  
  72. il void access(RG uint x){ RG uint t=; while (x) splay(x),ch[x][]=t,pushup(x),t=x,x=fa[x]; return; }
  73.  
  74. il void split(RG uint x){ access(x),splay(x); return; }
  75.  
  76. il void makeroot(RG uint x){ split(x),lazy[x]^=; return; }
  77.  
  78. il void link(RG uint x,RG uint y){ makeroot(x),fa[x]=y; return; }
  79.  
  80. il void cut(RG uint x,RG uint y){ makeroot(x),split(y),ch[y][]=fa[x]=,pushup(y); return; }
  81.  
  82. il void add(RG uint x,RG uint y,RG uint v){
  83. makeroot(x),split(y),(rev1[y]+=v)%=r64,(val[y]+=v)%=r64,(sum[y]+=v*(size[y]%r64))%=r64; return;
  84. }
  85.  
  86. il void times(RG uint x,RG uint y,RG uint v){
  87. makeroot(x),split(y),(rev1[y]*=v)%=r64,(rev2[y]*=v)%=r64,(val[y]*=v)%=r64,(sum[y]*=v)%=r64; return;
  88. }
  89. il uint query(RG uint x,RG uint y){ makeroot(x),split(y); return sum[y]; }
  90.  
  91. il void work(){
  92. n=gi(),q=gi(); RG uint u,v,c; for (RG uint i=;i<=n;++i) sum[i]=val[i]=rev2[i]=size[i]=;
  93. for (RG uint i=;i<n;++i) u=gi(),v=gi(),link(u,v);
  94. for (RG uint i=;i<=q;++i){
  95. scanf("%s",s); if (s[]=='+') u=gi(),v=gi(),c=gi(),add(u,v,c);
  96. if (s[]=='-') u=gi(),v=gi(),cut(u,v),u=gi(),v=gi(),link(u,v);
  97. if (s[]=='*') u=gi(),v=gi(),c=gi(),times(u,v,c);
  98. if (s[]=='/'){ u=gi(),v=gi(); printf("%u\n",query(u,v)); }
  99. }
  100. return;
  101. }
  102.  
  103. int main(){
  104. File("tree");
  105. work();
  106. return ;
  107. }

【国家集训队2012】tree(伍一鸣)的更多相关文章

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

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

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

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

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

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

  4. [国家集训队2012]tree(陈立杰)

    [国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示 ...

  5. [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)

    tree 时间限制: 3 Sec  内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...

  6. Tsinsen A1303. tree(伍一鸣) LCT

    LCT的各种操作... . cut link add mul size rev query 写的效率不够高... BZOJ上似乎TLE. ... A1303. tree(伍一鸣) 时间限制:2.5s  ...

  7. [国家集训队2012]middle

    http://cogs.pro:8080/cogs/problem/problem.php?pid=1763 二分答案x 把区间内>=x的数设为1,<x的数设为-1 左端点在[a,b]之间 ...

  8. luogu P2619 [国家集训队2]Tree I

    题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...

  9. [国家集训队2012]JZPFAR

    [国家集训队2012]JZPFAR 题目 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个(或多个)点距离( ...

  10. P2619 [国家集训队2]Tree I(最小生成树+二分)

    P2619 [国家集训队2]Tree I 每次二分一个$x$,每条白边加上$x$,跑最小生成树 统计一下满足条件的最小值就好了. to me:注意二分不要写挂 #include<iostream ...

随机推荐

  1. css 超出隐藏显示...

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  2. 微信开发模式 api 接口文档简介

    微信公众平台分为订阅号和服务号,服务号提供9大接口,需要通过微信认证后才能使用这些接口.认证费用300元.下面是接口的大致介绍: 1. 语音识别:通过语音识别接口,用户发送的语音,将会同时给出语音识别 ...

  3. QT Creator 快速入门教程 读书笔记(二)

    一 窗口部件 基础窗口部件QWidget类是所有用户界面对象的基类,窗口和控件都是直接或间接继承自 QWidget,下面我们来看一个很简单的例子: 窗口部件(Widget)简称部件,是QT中建立界面的 ...

  4. iOS 组件化

    iOS 组件化介绍 随着应用需求逐步迭代,应用的代码体积将会越来越大,为了更好的管理应用工程,我们开始借助CocoaPods版本管理工具对原有应用工程进行拆分.但是仅仅完成代码拆分还不足以解决业务之间 ...

  5. MapReduce简介以及详细配置

    1.MapReduce(一个分布式运算框架)将数据分为数据块,发送到不同的节点,并行方式处理. 2.NodeManager和DataNode在一个节点上,程序与数据在一个节点. 3.内容分为两个部分 ...

  6. C++—动态内存管理之深入探究new和delete

    C++中程序存储空间除栈空间和静态区外,每个程序还拥有一个内存池,这部分内存被称为自由空间(free store)或堆(heap).程序用堆来存储动态分配的对象,即,那些程序运行时分配的对象.动态对象 ...

  7. Spring:利用PerformanceMonitorInterceptor来协助应用性能优化

    前段时间对公司产品做性能优化,如果单依赖于测试,进度就会很慢.所以就通过对代码的方式来完成,并以此来加快项目进度.具体的执行方案自然就是要知道各个业务执行时间,针对业务来进行优化. 因为项目中使用了S ...

  8. 如何使用ArcGIS发布LiDAR 点云

    LiDAR--Light Detection And Ranging,即激光探测与测量技术. 下面将介绍如何使用ARCGIS来发布LiDAR的成果点云数据. LiDAR的点云数据一般格式为LAS.在A ...

  9. 模块化规范Common.js,AMD,CMD

    随着网站规模的不断扩大,嵌入网页中的javascript代码越来越大,开发过程中存在大量问题,如:协同开发,代码复用,大量文件引入,命名冲突,文件依赖. 模块化编程称为迫切的需求. 所谓的模块,就是实 ...

  10. 关于js参数传递矛盾新理解

    之前看了很多人的解释,说js中,函数的参数传递都是值传递中不理解. 他们无非举了两个例子 在这两个例子中,第二个例子可以看出参数是由值传递的.因为函数内对象的变化没有影响到函数外对象的变化.但是在第一 ...