Chiimo's Code Style for OI
甲 概览
所有的 #include
指令必须放置于整个程序开头。
不应该使用 using namespace std;
。
在必要时应该使用 using foo::bar;
。
main
函数应该放置于整个程序末尾。
应当使用 int
代替 bool
表示逻辑值(空间真不够除外,但正常题目不会那么毒瘤罢)。
乙 预编译指令
#include
中,C 标准库头文件必须使用 .h
后缀,而不是 c
前缀(旧习难改)。
尽量不使用不带 .h
后缀的库文件。
#include
中,C 标准库头文件应该放置于 C++ 标准库头文件前,其它头文件(如果有)应放置于最后。
尽量使用 #define
声明常量与常用函数(比如max
,min
,swap
之类的)。
可以使用 #include <foo>
时绝不使用 #include "foo"
。
丙 缩进
对于每个代码块,使用 2 空格或等长的 Tab 缩进。
丁 花括号
花括号必须遵循「花括号不换行」的原则。
对于「花括号不换行」,左花括号的左边必须有且仅有一个空格。
所有右花括号必须与上一级代码块的缩进相同。
if(e) {
sth;
} else {
sth;
}
戊 行
除 for
中的三个语句外,每行不能有超过一个语句。如果需要一行内求值多个表达式,可以使用等效的逗号表达式替代。
多个意义独立的代码块之间应该用空行隔开。
右花括号前不应该有多余的空行。
不应该有两个连续的空行。
非空行尾不应该有多余的空格。
函数、成员函数、结构体、全局变量块之间可以用空行隔开。
己 函数
main
函数的返回值类型必须是 int
,可以省略 return 0;
。
空函数体可以使用 {}
。
传参时,应该根据实际需要使用「全局变量传递」和「值传递」。
庚 变量
尽量少使用全局变量。
局部变量应当在函数开头定义(for
语句的循环变量除外),变量名不应该与上一个块中的变量重名,尽量不与全局变量重名。
辛 空格
逗号 , 与 for 中的分号 ; 后面必须有一个空格,前面不能有空格。
左圆(方)括号后、右圆(方)括号前不可以加一个空格。
双目运算符、三目运算符的两侧必须有一个空格。
单目运算符的两侧不能有空格。
冒号的两侧必须有一个空格。
struct Edge {
int x;
Edge() : x(0) {}
}
流程控制关键字之后,函数名之后,左圆括号前均不能有空格。
对于「花括号不换行」,do-while
结构的 do
之后,左花括号前必须有一个空格,while
前必须有一个空格。
模板参数表中,如果右方括号前不得不加一个空格,则可以在对应的左方括号后加一个空格,为了对称。
.、->、:: 的两边不能有空格。
壬 指针与引用
绝对不使用引用。
在描述类型名时,指针符号 *
与左侧的类型名之间必须有一个空格,与右侧的其它关键字之间不能有空格,如 char *const
。
在定义变量、函数返回值、参数时,指针符号 *
与左侧的类型名之间必须有一个空格,与右侧的变量、函数、参数名之间不能有空格。
癸 其他
注释只使用 /* */
类型,最好不与代码写在一行。
输入时的 for
循环最好压成一行,但如果实在太长可以换一行写。
尽量不使用 STL
与其他 C++ 的奇奇怪怪的东西,按照 C 标准来。
Example Code
#include<stdio.h>
#include<iostream>
#define reg register
#define ri reg int
#define rep(i, x, y) for(ri i = x; i <= y; ++i)
#define nrep(i, x, y) for(ri i = x; i >= y; --i)
#define DEBUG 1
#define ll long long
#define MAXN 500010
#define il inline
#define mid ((l + r) >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define len (r - l + 1)
#define max(i, j) (i) > (j) ? (i) : (j)
#define min(i, j) (i) < (j) ? (i) : (j)
#define read(i) io.READ(i)
#define print(i) io.WRITE(i)
#define push(i) io.PUSH(i)
using namespace std;
struct IO {
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
char buf[MAXSIZE], *p1, *p2;
char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
IO() : p1(buf), p2(buf), pp(pbuf) {}
~IO() {
fwrite(pbuf, 1, pp - pbuf, stdout);
}
#endif
il char gc() {
#if DEBUG
return getchar();
#endif
if(p1 == p2)
p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
return p1 == p2 ? ' ' : *p1++;
}
il bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
template <class T>
il void READ(T &x) {
register double tmp = 1;
register bool sign = 0;
x = 0;
register char ch = gc();
for(; !isdigit(ch); ch = gc())
if(ch == '-') sign = 1;
for(; isdigit(ch); ch = gc())
x = x * 10 + (ch - '0');
if(ch == '.')
for(ch = gc(); isdigit(ch); ch = gc())
tmp /= 10.0, x += tmp * (ch - '0');
if(sign) x = -x;
}
il void READ(char *s) {
register char ch = gc();
for(; blank(ch); ch = gc());
for(; !blank(ch); ch = gc())
*s++ = ch;
*s = 0;
}
il void READ(char &c) {
for(c = gc(); blank(c); c = gc());
}
il void PUSH(const char &c) {
#if DEBUG
putchar(c);
#else
if(pp - pbuf == MAXSIZE) {
fwrite(pbuf, 1, MAXSIZE, stdout);
pp = pbuf;
}
*pp++ = c;
#endif
}
template <class T>
il void WRITE(T x) {
if(x < 0) {
x = -x;
PUSH('-');
}
static T sta[35];
T top = 0;
do {
sta[top++] = x % 10;
x /= 10;
} while(x);
while(top)
PUSH(sta[--top] + '0');
}
template <class T>
il void WRITE(T x, char lastChar) {
WRITE(x);
PUSH(lastChar);
}
} io;
ll n, m;
struct Edge {
ll next, to;
} h[MAXN << 1];
ll head[MAXN << 1];
ll tot, to[MAXN], w[MAXN], wt[MAXN];
ll a[MAXN << 2], laz[MAXN << 2];
ll son[MAXN], id[MAXN], fa[MAXN], cnt, dep[MAXN], siz[MAXN], top[MAXN];
ll res;
il void add(ll u, ll v) {
h[++tot].next = head[u];
h[tot].to = v;
head[u] = tot;
}
il void pushdown(ll rt, ll lenn) {
laz[rt << 1] += laz[rt];
laz[rt << 1 | 1] += laz[rt];
a[rt << 1] += laz[rt] * (lenn - (lenn >> 1));
a[rt << 1 | 1] += laz[rt] * (lenn >> 1);
laz[rt] = 0;
}
il void build(ll rt, ll l, ll r) {
if(l == r) {
a[rt] = wt[l];
return;
}
build(lson);
build(rson);
a[rt] = (a[rt << 1] + a[rt << 1 | 1]);
}
il void query(ll rt, ll l, ll r, ll s, ll t) {
if(s <= l && r <= t) {
res += a[rt];
return;
} else {
if(laz[rt]) pushdown(rt, len);
if(s <= mid) query(lson, s, t);
if(t > mid) query(rson, s, t);
}
}
il void update(ll rt, ll l, ll r, ll s, ll t, ll k) {
if(s <= l && r <= t) {
laz[rt] += k;
a[rt] += k * len;
} else {
if(laz[rt]) pushdown(rt, len);
if(s <= mid) update(lson, s, t, k);
if(t > mid) update(rson, s, t, k);
a[rt] = (a[rt << 1] + a[rt << 1 | 1]);
}
}
il ll qRange(ll x, ll y) {
ll ans = 0;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
res = 0;
query(1, 1, n, id[top[x]], id[x]);
ans += res;
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
res = 0;
query(1, 1, n, id[x], id[y]);
ans += res;
return ans;
}
il void updSon(ll x, ll k) {
update(1, 1, n, id[x], id[x] + siz[x] - 1, k);
}
il void dfs1(ll x, ll f, ll deep) {
dep[x] = deep;
fa[x] = f;
siz[x] = 1;
ll maxson = -1;
for(ll i = head[x]; i; i = h[i].next) {
ll y = h[i].to;
if(y == f) continue;
dfs1(y, x, deep + 1);
siz[x] += siz[y];
if(siz[y] > maxson) son[x] = y, maxson = siz[y];
}
}
il void dfs2(ll x, ll rt) {
id[x] = ++cnt;
wt[cnt] = w[x];
top[x] = rt;
if(!son[x]) return;
dfs2(son[x], rt);
for(ll i = head[x]; i; i = h[i].next) {
ll y = h[i].to;
if(y == fa[x] || y == son[x]) continue;
dfs2(y, y);
}
}
int main() {
read(n), read(m);
rep(i, 1, n) read(w[i]);
rep(i, 1, n - 1) {
ll a, b;
read(a), read(b);
add(a, b);
add(b, a);
}
dfs1(1, 0, 1);
dfs2(1, 1);
build(1, 1, n);
while(m--) {
ll k, x, y;
read(k);
if(k == 1) {
read(x), read(y);
update(1, 1, n, id[x], id[x], y);
} else if(k == 2) {
read(x), read(y);
updSon(x, y);
} else {
read(x);
print(qRange(1, x));
puts("");
}
}
return 0;
}