http://blog.csdn.net/lyhypacm/article/details/6734748
dfs序是針對某條路徑, 利用根到路徑
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
const double pi=cos(-1.);
const double eps=10e-6;
const double eps1=10e-9;
const int inf=0x7fffffff;
///const int inf=0x3f3f3f3f;
const long long infl=1ll<<62;
///******macro defination******///
#define cas(a) int a; scanf("%d", &a); while (a--)
#define cas1(x, a) int a; scanf("%d", &a); for (int x=1; x<=a; ++x)
#define int(a) int a; scanf("%d", &a)
#define char(a) char a; scanf("%c", &a)
#define strr(a, x) char a[x]; scanf("%s", &a)
#define clean(a, x) memset (a, x, sizeof(a));
#define copy(a, b) memcpy(a, b, sizeof(a));
#define up(x,a) for(int x=0; x<a; ++x)
#define down(x,a) for(int x=a-1; x>=0; --x)
#define up1(x,a) for (int x=1; x<=a; ++x)
#define debug(a) printf("here is %d!!!\n", a);
///*** mathmatics ***///
#define sqr(x) (x)*(x)
#define abs(x) (x)>0?(x):(-(x))
#define zero(x) (x)<eps && (x)>eps
#define lowbit(x) ((x)&(-(x)))
///*** for STL ***///
#define fst first
#define scd second
#define pb push_back
#define mp makepair
#define lb lower_bound
#define ub upper_bound
///****** by Geners ******///
typedef long long ll;
typedef unsigned int UI;
using namespace std;
const int mod=1000000007;
const int maxn=100000+123;
#define vex edge[p].v
int w[maxn];
struct Edge{int v, next;}edge[2*maxn];
int head[maxn], cnt;
void addedge(int u, int v){
edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++;
}
///*** graphic theory***///
ll C[2*maxn];
int N;
int Query(int x){
for (int res=0; ; res+=C[x], x-=lowbit(x))if(x==0)return res;
}
void Update(int x, int v){
for (;x<=N; x+=lowbit(x))C[x]+=v;
}
void IUpdate(int s, int t, int v){
Update(t+1, -v); Update(s, v);
}
///*** Binary Indexed Tree ***///
int node[maxn];
int d[maxn], fath[maxn][50], l[maxn], r[maxn], idx;
void dfs(int u, int fa)
{
l[u]=++idx;
for (int p=head[u]; ~p; p=edge[p].next)
{
if(vex==fa)continue;
fath[vex][0]=u;
int pa=u;
d[vex]=d[u]+1;
for (int k=0; fath[pa][k]; ++k)
{
fath[vex][k+1]=fath[pa][k];
pa=fath[pa][k];
}
dfs(vex, u);
}
r[u]=++idx;
}
int LCA(int u, int v)
{
if(u==v)return u;
if(d[u]<d[v])swap(u, v);
int m=d[u]-d[v];/// 將 u, v 調到同深度
for (int i=0; m; m>>=1, ++i)if(m&1)u=fath[u][i];
if(u==v)return u;
for (int i=0; u^v; )
{
if(fath[u][i]!=fath[v][i] || (fath[u][i]==fath[v][i] && i==0))
u=fath[u][i], v=fath[v][i], ++i;
else --i;
}
return u;
}
void init()
{
clean(head, -1); cnt=0;
clean(C, 0); clean(fath, 0);
}
int main ()
{
int n, m, q;
while (~scanf("%d%d%d", &n, &m, &q))
{
init();
for (int i=1; i<=n; ++i)
{
scanf("%d", node+i);
}
for (int i=0; i<m; ++i)
{
int a, b; scanf("%d%d", &a, &b);
addedge(a, b); addedge(b, a);
}
d[1]=0; idx=0;
dfs(1, -1);
N=n<<1;
for (int i=0; i<q; ++i)
{
char op[5]; scanf("%s", op);
if(op[0]=='I' || op[0]=='D')
{
int a, b, c; scanf("%d%d%d", &a, &b, &c);
if(op[0]=='D')c=-c;
///debug(l[a]);
IUpdate(1, l[a], c);
IUpdate(1, l[b], c);
int lca=LCA(a, b);
///debug(lca);
IUpdate(1, l[lca], -c);
if(lca!=1)IUpdate(1, l[lca]-1, -c);
}
if(op[0]=='Q')
{
int a; scanf("%d", &a);
int d=Query(l[a])-Query(r[a]);
printf("%d\n", node[a]+d);
}
}
}
return 0;
}
用樹狀數組, 單點修改的點取左端點座標, 左右端點的意義爲 左端點爲當前點, 直到右端點位置都是該點的子樹
因此查詢子樹的操作變爲對某點對應左右端點的查詢
#define vex edge[p].v
int w[maxn];
struct Edge{int v, next;}edge[2*maxn];
int head[maxn], cnt;
void addedge(int u, int v){
edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++;
}
///*** graphic theory***///
int C[2*maxn];
int N;
int Query(int x){
for (int res=0; ; res+=C[x], x-=lowbit(x))if(x==0)return res;
}
void Update(int x, int v){
for (;x<=N; x+=lowbit(x))C[x]+=v;
}
///----------------
///----------------
void IUpdate(int s, int t, int v){
Update(t+1, -v); Update(s, v);
}
///*** Binary Indexed Tree ***///
int idx, l[maxn], r[maxn];
void dfs(int u, int fa)
{
l[u]=++idx;
for (int p=head[u]; ~p; p=edge[p].next)
{
if(vex==fa)continue;
dfs(vex, u);
}
r[u]=idx;
}
void init()
{
clean (head, -1); cnt=0;
idx=0;
}
int main ()
{
int n, k;
while (~scanf("%d", &n))
{
init();
for (int i=1; i<n; ++i)
{
int a, b; scanf("%d%d", &a, &b);
addedge(a, b); addedge(b, a);
}
idx=0;
dfs(1, -1);
//for (int i=1; i<=idx; ++i)printf("l %d %d %d\n", i, l[i], r[i]);
N=idx;
clean(C, 0);
for (int i=1; i<=idx; ++i)
Update(i, 1);
int q; scanf("%d", &q);
while (q--)
{
char op[5]; int a; scanf("%s%d", op, &a);
if(op[0]=='C')
{
//printf("%d", t);
int t=Query(l[a])-Query(l[a]-1);
t=(t^1)-t;
// printf(" %d\n", t);
Update(l[a], t);
}else
{
printf("%d\n", Query(r[a])-Query(l[a]-1));
}
}
}
return 0;
}