[51nod1462]树据结构

题面:

  给一颗以1为根的树。
  每个点有两个权值:vi, ti,一开始全部是零。
 Q次操作:
  读入o, u, d
  o = 1 对u到根上所有点的vi += d 
  o = 2 对u到根上所有点的ti += vi * d
  最后,输出每个点的ti值(n, Q <= 100000)
  有50%的数据N,Q <= 10000

  注:所有数64位整数不会爆。

一开始以为是链剖板子题,结果发现两个标记没法共存(就是说要更新某个标记的话另一个标记得传下去)

由swm大爷的教导可得T_T,可以搞个3*3的矩阵当标记...

1,0,0

0,1,0

v,t,1

操作1的话就是乘上

1,0,0

0,1,0

d,0,1

操作2的话就是乘上

1,d,0

0,1,0

0,0,1

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #define ll long long
 7 #define ui unsigned int
 8 #define ull unsigned long long
 9 const int maxn=100023,mxnode=maxn<<1;
10 struct zs{int too,pre;}e[maxn];int tot,last[maxn];
11 struct mat{ll mp[3][3];}tag[mxnode],nul={1,0,0,0,1,0,0,0,1};
12 int lc[mxnode],rc[mxnode],tt;
13 int dfn[maxn],tim,fa[maxn],bel[maxn],sz[maxn];
14 int i,j,k,n,m;
15 int L,R;mat TAG;
16 ll an[maxn];
17
18 int ra,fh;char rx;
19 inline int read(){
20     rx=getchar(),ra=0,fh=1;
21     while((rx<‘0‘||rx>‘9‘)&&rx!=‘-‘)rx=getchar();
22     if(rx==‘-‘)fh=-1,rx=getchar();
23     while(rx>=‘0‘&&rx<=‘9‘)ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
24 }
25
26 mat operator *(mat a,mat b){
27     mat c;
28     int i,j,k;
29     for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=c.mp[i][j]=0;k<3;k++)
30         c.mp[i][j]+=a.mp[i][k]*b.mp[k][j];
31     return c;
32 }
33
34 inline void pushdown(int x){
35     if(!tag[x].mp[0][1]&&!tag[x].mp[2][0])return;
36     int l=lc[x],r=rc[x];
37     tag[l]=tag[l]*tag[x],tag[r]=tag[r]*tag[x],
38     tag[x]=nul;
39 }
40 void insert(int x,int a,int b){
41     if(L<=a&&R>=b){tag[x]=tag[x]*TAG;return;}
42     pushdown(x);
43     int mid=a+b>>1;
44     if(L<=mid)insert(lc[x],a,mid);
45     if(R>mid)insert(rc[x],mid+1,b);
46 }
47 void dfss(int x,int a,int b){
48     if(a==b){an[a]=tag[x].mp[2][1];return;}
49     pushdown(x);
50     int mid=a+b>>1;
51     dfss(lc[x],a,mid),dfss(rc[x],mid+1,b);
52 }
53 void build(int a,int b){
54     int x=++tt;tag[x]=nul;
55     if(a==b)return;
56     int mid=a+b>>1;
57     lc[x]=tt+1,build(a,mid),rc[x]=tt+1,build(mid+1,b);
58 }
59
60
61 void dfs(int x){
62     sz[x]=1;
63     for(int i=last[x];i;i=e[i].pre)
64         fa[e[i].too]=x,dfs(e[i].too),sz[x]+=sz[e[i].too];
65 }
66 void dfs2(int x,int chain){
67     int i,mx=0;
68     bel[x]=chain,dfn[x]=++tim;
69     for(i=last[x];i;i=e[i].pre)if(sz[e[i].too]>sz[mx])mx=e[i].too;
70     if(!mx)return;
71     dfs2(mx,chain);
72     for(i=last[x];i;i=e[i].pre)if(e[i].too!=mx)dfs2(e[i].too,e[i].too);
73 }
74 void run(int x){
75     while(bel[x]!=bel[1])
76         L=dfn[bel[x]],R=dfn[x],insert(1,1,n),
77         x=fa[bel[x]];
78     L=dfn[bel[1]],R=dfn[x],insert(1,1,n);
79 }
80
81 inline void ins(int a,int b){
82     e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;
83 }
84 int main(){
85     n=read();
86     for(i=2;i<=n;i++)ins(read(),i);
87     dfs(1),dfs2(1,1);
88     build(1,n);
89     int id,x,d;
90     for(m=read();m;m--){
91         id=read(),x=read(),d=read();TAG=nul;
92         if(id==1)TAG.mp[2][0]=d;else TAG.mp[0][1]=d;
93         run(x);
94     }
95     dfss(1,1,n);
96     for(i=1;i<=n;i++)printf("%lld\n",an[dfn[i]]);
97 }

还是第一次见这种题。。

时间: 2024-11-29 05:20:53

[51nod1462]树据结构的相关文章

URAL 1822. Hugo II&#39;s War 树的结构+二分

1822. Hugo II's War Time limit: 0.5 second Memory limit: 64 MB The glorious King Hugo II has declared a war-a war that is holy, victorious, almost bloodless, but ruinous! Right after declaring the war the king has started summoning the army. He plans

树型结构

树型结构的基本概念 对大量的输入数据,链表的线性访问时间太慢,不宜使用.本文探讨另外一种重要的数据结构----树,其大部分时间可以保证操作的运行平均时间复杂度为O(logN),第一部分先来看一下树的一些预备知识. 首先看一下树形结构的样子,下图代表的是树型结构的一般形态: 由上图看得出树是一些节点的集合,总结一下树的一些基本概念: 1.结点:树中的数据元素都称之为结点 2.根:最上面的结点称之为根,一颗树只有一个根且由根发展而来,从另外一个角度来说,每个结点都可以认为是其子树的根 3.父亲:结点

URAL 1822. Hugo II&amp;#39;s War 树的结构+二分

1822. Hugo II's War Time limit: 0.5 second Memory limit: 64 MB The glorious King Hugo II has declared a war-a war that is holy, victorious, almost bloodless, but ruinous! Right after declaring the war the king has started summoning the army. He plans

Android无限级树状结构

通过对ListView简单的扩展.再封装,即可实现无限层级的树控件TreeView. 1 package cn.asiontang.nleveltreelistview; 2 3 import android.annotation.TargetApi; 4 import android.content.Context; 5 import android.os.Build; 6 import android.util.AttributeSet; 7 import android.view.View

在Silverlight中使用HierarchicalDataTemplate为TreeView实现递归树状结构

将实体绑定到TreeView控件,实现树状结构的显示,如下图所示.这个功能通过HierarchicalDataTemplate实现. ? 1. 业务实体 作为举例,我定义了一个大家都很熟悉的Folder类型,即文件夹.我们都知道,文件夹又可以包含子文件夹,而且可以多层嵌套.所以,这是一个递归的结构体. public class Folder { public string Name { get; set; } public ObservableCollection<Folder> Folder

c# 递归、树状结构

1.树状结构 treeView.Nodes.Clear(); TreeNode tree = new TreeNode(); tree.Text = "字母"; treeView.Nodes.Add(tree); // tree.Nodes.Add("A"); TreeNode tree1 = new TreeNode(); tree1.Text = "汉字"; treeView.Nodes.Add(tree1); TreeNode a = ne

json格式转树状结构

转自:http://rockyuse.iteye.com/blog/1541308 /** * json格式转树状结构 * @param {json} json数据 * @param {String} id的字符串 * @param {String} 父id的字符串 * @param {String} children的字符串 * @return {Array} 数组 */ function transData(a, idStr, pidStr, chindrenStr){ var r = []

Java文件目录树状结构:控制台打印某个文件夹下的文件目录树状结构

1 package com.zhen.file; 2 3 import java.io.File; 4 5 /* 6 * 控制台打印某个文件夹下的文件目录树状结构 7 * 递归算法 8 */ 9 10 public class FileTree { 11 12 public static void main(String[] args) { 13 File file =new File("D:/Github/JavaTest"); 14 PrintFile(file, 0); 15 }

lua 如何输出树状结构的table?

为了让游戏前端数据输出更加条理,做了一个简单树状结构来打印数据. ccmlog.lua local function __tostring(value, indent, vmap) local str = '' indent = indent or '' vmap = vmap or {} --递归结束条件 if (type(value) ~= 'table') then if (type(value) == 'string') then --字符串 str = string.format("[