记录编号 |
144834 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[ZJOI 2008]树的统计Count |
最终得分 |
100 |
用户昵称 |
Asm.Def |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.281 s |
提交时间 |
2014-12-29 22:46:56 |
内存使用 |
4.09 MiB |
显示代码纯文本
/*====================Asm.Def========================*/
#include <iostream>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <ctime>
using namespace std;
inline void getd(int &x){
char c = getchar();bool minus = 0;
while(!isdigit(c) && c != '-')c = getchar();
if(c == '-')minus = 1, c = getchar();
x = c - '0';
while(isdigit(c = getchar()))x = x * 10 + c - '0';
if(minus)x = -x;
}
/*======================================================*/
const int maxn = 30005, INF = 0x7fffffff;
int N, Val[maxn];
struct SegT{
SegT *son[2];
int L, R, mid, Sum, Max;
inline void update(){
Sum = son[0]->Sum + son[1]->Sum;
Max = max(son[0]->Max, son[1]->Max);
}
inline void init(int, int);
inline void Set(int i, int x){
if(L == R){Sum = Max = x;return;}
if(i <= mid)son[0]->Set(i, x);
else son[1]->Set(i, x);
update();
}
inline int qsum(int l, int r){
if(l == L && r == R)return Sum;
if(r <= mid)return son[0]->qsum(l, r);
if(l > mid)return son[1]->qsum(l, r);
return son[0]->qsum(l, mid) + son[1]->qsum(mid+1, r);
}
inline int qmax(int l, int r){
if(l == L && r == R)return Max;
if(r <= mid)return son[0]->qmax(l, r);
if(l > mid)return son[1]->qmax(l, r);
return max(son[0]->qmax(l, mid), son[1]->qmax(mid+1, r));
}
}Seg, Segnode[maxn << 2];
inline void SegT::init(int l, int r){
static int Segptr = 0;
L = l, R = r, mid = (l + r) >> 1;
if(L == R){
Sum = Max = Val[L];
if(L == 0)Max = -INF;
son[0] = son[1] = NULL;
return;
}
son[0] = Segnode + Segptr++;son[1] = Segnode + Segptr++;
son[0]->init(l, mid), son[1]->init(mid+1, r);
Max = max(son[0]->Max, son[1]->Max);
Sum = son[0]->Sum + son[1]->Sum;
}
struct Node{
struct Eto{Node *to;Eto *next;Eto(Node *t):to(t){};};
Eto *adj;
Node *Son, *pre, *anc;
int dep, size, val, Loc/*在Seg中的位置*/;
inline void Addadj(Node *to){Eto *t = new Eto(to);t->next = adj;adj = t;}
inline void dfs(){
register Eto *it;
register Node *t;
size = 1;
register int MaxS = 0;
for(it = adj;it != NULL;it = it->next){
t = it->to;
if(t == pre)continue;
t->pre = this;t->dep = dep + 1;
t->dfs();
size += t->size;
if(t->size > MaxS)Son = t, MaxS = t->size;
}
}
inline void build(){//注意SegT 0位置的Max = -INF
register Eto *it;
register Node *t;
static int iter = 1;
Loc = iter;
Val[iter++] = val;
if(Son == NULL)return;
Son->anc = anc;
Son->build();
for(it = adj;it != NULL;it = it->next){
t = it->to;
if(t == pre || t == Son)continue;
t->anc = t;
t->build();
}
}
}node[maxn];
inline void init(){
getd(N);
register int i, a, b;
for(i = 1;i < N;++i){
getd(a), getd(b);
node[a].Addadj(node + b);
node[b].Addadj(node + a);
}
for(i = 1;i <= N;++i)
getd(node[i].val);
srand(time(NULL));
register Node *root = node + (rand() % N + 1);
root->pre = node, root->dep = 1;
root->dfs();
root->anc = root;
root->build();
Seg.init(1, N);
}
inline int Qsum(int a, int b){
Node *u = node + a, *v = node + b;
int ans = 0;
while(u->anc != v->anc){
if(u->anc->dep < v->anc->dep)swap(u, v);
ans += Seg.qsum(u->anc->Loc, u->Loc);
u = u->anc->pre;
}
if(u->Loc > v->Loc)swap(u, v);
ans += Seg.qsum(u->Loc, v->Loc);
return ans;
}
inline int Qmax(int a, int b){
Node *u = node + a, *v = node + b;
int ans = -INF;
while(u->anc != v->anc){
if(u->anc->dep < v->anc->dep)swap(u, v);
ans = max(ans, Seg.qmax(u->anc->Loc, u->Loc));
u = u->anc->pre;
}
if(u->dep < v->dep)swap(u, v);
ans = max(ans, Seg.qmax(v->Loc, u->Loc));
return ans;
}
int main(){
#if defined DEBUG
freopen("test", "r", stdin);
freopen("output.txt", "w", stdout);
#else
freopen("bzoj_1036.in", "r", stdin);
freopen("bzoj_1036.out", "w", stdout);
#endif
init();
register int T, a, b;
char opt[10], *End;
getd(T);
while(T--){
End = opt;
while(!isalpha(*End = getchar()));++End;
while(isalpha(*End = getchar()))++End;
getd(a), getd(b);
if(End - opt == 6)//Change
Seg.Set(node[a].Loc, b);
else if(opt[1] == 'M')//QMAX
printf("%d\n", Qmax(a, b));
else//QSUM
printf("%d\n", Qsum(a, b));
}
#if defined DEBUG
cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
#endif
return 0;
}