# BZOJ4034 [HAOI2015]T2

  1 /**************************************************************
2     Problem: 4034
3     User: rausen
4     Language: C++
5     Result: Accepted
6     Time:1128 ms
7     Memory:21796 kb
8 ****************************************************************/
9
10 #include <cstdio>
11
12 using namespace std;
13 typedef long long ll;
14 const int N = 1e5 + 5;
15 const int Maxlen = N * 50;
16
18 inline void print(ll);
19
20 struct edge {
21     int next, to;
22     edge(int _n = 0, int _t = 0) : next(_n), to(_t) {}
23 } e[N << 1];
24
25 int first[N], tot;
26
27 struct seg {
28     seg *ls, *rs;
29     int times;
30     ll v, tag;
31
32     seg() {
33         ls = rs = NULL;
34         v = tag = times = 0;
35     }
36
37     #define Len (1 << 16)
38     inline void* operator new(size_t) {
39         static seg *mempool, *c;
40         if (c == mempool)
41             mempool = (c = new seg[Len]) + Len;
42         *c = seg();
43         return c++;
44     }
45     #undef Len
46
47     inline void push() {
48         if (v) {
49             if (ls) ls -> v += v;
50             if (rs) rs -> v += v;
51             v = 0;
52         }
53         if (tag) {
54             if (ls) ls -> tag += tag;
55             if (rs) rs -> tag += tag;
56             tag = 0;
57         }
58     }
59
60     #define mid (l + r >> 1)
61     void build(int l, int r, ll *a, int *b) {
62         if (l == r) {
63             v = a[l], times = b[l];
64             return;
65         }
66         ls = new()seg, rs = new()seg;
67         ls -> build(l, mid, a, b), rs -> build(mid + 1, r, a, b);
68     }
69
70     void modify(int l, int r, int L, int R, int d) {
71         if (L <= l && r <= R) {
72             v += d;
73             return;
74         }
75         push();
76         if (L <= mid) ls -> modify(l, mid, L, R, d);
77         if (mid < R) rs -> modify(mid + 1, r, L, R, d);
78     }
79
80     void Modify(int l, int r, int L, int R, int dep, int d) {
81         if (L <= l && r <= R) {
82             v -= 1ll * d * (dep - 1), tag += d;
83             return;
84         }
85         push();
86         if (L <= mid) ls -> Modify(l, mid, L, R, dep, d);
87         if (mid < R) rs -> Modify(mid + 1, r, L, R, dep, d);
88     }
89
90     ll query(int l, int r, int pos) {
91         if (l == r) return v + tag * times;
92         push();
93         if (pos <= mid) return ls -> query(l, mid, pos);
94         return rs -> query(mid + 1, r, pos);
95     }
96     #undef mid
97 } *T;
98
99 struct tree_node {
100     int fa, v, dep;
101     int st, ed;
102 } tr[N];
103
104 int n, m, cnt_seq;
105 ll a[N];
106 int b[N];
107
108 char buf[Maxlen], *c = buf;
109 int Len;
110
111 inline void Add_Edges(int x, int y) {
112     e[++tot] = edge(first[x], y), first[x] = tot;
113     e[++tot] = edge(first[y], x), first[y] = tot;
114 }
115
116 #define y e[x].to
117 void dfs(int p) {
118     int x;
119     a[tr[p].st = ++cnt_seq] = a[tr[tr[p].fa].st] + tr[p].v;
120     b[cnt_seq] = tr[p].dep;
121     for (x = first[p]; x; x = e[x].next)
122         if (y != tr[p].fa) {
123             tr[y].fa = p, tr[y].dep = tr[p].dep + 1;
124             dfs(y);
125         }
126     tr[p].ed = cnt_seq;
127 }
128 #undef y
129
130 int main() {
131     Len = fread(c, 1, Maxlen, stdin);
132     buf[Len] = '\0';
133     int i, oper, x;
135     for (i = 1; i <= n; ++i) tr[i].v = read();
136     for (i = 1; i < n; ++i)
138     dfs(1);
139     T = new()seg;
140     T -> build(1, n, a, b);
141     while (m--) {
143         if (oper == 1) T -> modify(1, n, tr[x].st, tr[x].ed, read());
144         if (oper == 2) T -> Modify(1, n, tr[x].st, tr[x].ed, tr[x].dep, read());
145         if (oper == 3) print(T -> query(1, n, tr[x].st));
146     }
147     return 0;
148 }
149
151     static int x, sgn;
152     x = 0, sgn = 1;
153     while (*c < '0' || '9' < *c) {
154         if (*c == '-') sgn = -1;
155         ++c;
156     }
157     while ('0' <= *c && *c <= '9')
158         x = x * 10 + *c - '0', ++c;
159     return sgn * x;
160 }
161
162 inline void print(ll t) {
163     int tot = 0, pr[25];
164     if (t < 0) putchar('-'), t = -t;
165     tot = 0;
166     while (t)
167         pr[++tot] = t % 10, t /= 10;
168     if (!tot) putchar('0');
169     while (tot) putchar(pr[tot--] + '0');
170     putchar('\n');
171 }
View Code

By Xs酱~ 转载请说明 博客地址：http://www.cnblogs.com/rausen
posted on 2015-05-04 22:15  Xs酱~  阅读(283)  评论(1编辑  收藏  举报