树形结构转换线性结构的方法(lca倍增)

这个讲的还不错的, 整理的很全

  http://blog.csdn.net/lyhypacm/article/details/6734748

hdu 3966

dfs序是针对某条路径, 利用根到路径

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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=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
#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]>=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



poj 3321 

用树状数组, 单点修改的点取左端点坐标, 左右端点的意义为 左端点为当前点, 直到右端点位置都是该点的子树

因此查询子树的操作变为对某点对应左右端点的查询

#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


你可能感兴趣的:(ACM,数据结构,ACM,图论)