1103 POI2007 大都市meg

树链剖分水过,单点修改,树状数组即可。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define N 250100
using namespace std;

int n, m, nowplace = 0;
int p[N] = {0}, next[N], v[N], bnum = 0;
int son[N] = {0}, fa[N], w[N], top[N], deep[N] = {0}, num[N];
int t[N] = {0};

int lowbit(int x) { return x & -x; }

void dfs_1(int now, int fat)
{
    int k = p[now]; num[now] = 1; int maxson = 0;
    fa[now] = fat; deep[now] = deep[fat] + 1;
    while (k)
    {
        dfs_1(v[k], now);
        if (num[v[k]] > maxson)
        {
            maxson = num[v[k]];
            son[now] = v[k];
        }
        num[now] += num[v[k]];
        k = next[k];
    }
}

void dfs_2(int now, int nowtop)
{
    int k = p[now]; w[now] = ++nowplace; top[now] = nowtop;
    if (son[now]) dfs_2(son[now], nowtop);
    while (k)
    {
        if (v[k] != son[now])
            dfs_2(v[k], v[k]);
        k = next[k];
    }
}

void add(int now, int addnum)
{
    while (now <= n)
    {
        t[now] += addnum;
        now += lowbit(now);
    }
    return;
}

int task(int now)
{
    int ans = 0;
    while (now)
    {
        ans += t[now];
        now -= lowbit(now);
    }
    return ans;
}

int ask(int u, int v)
{
    int f1 = top[u], f2 = top[v];
    if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); }
    if (f1 == f2) return task(max(w[u], w[v])) - task(min(w[u], w[v])-1);
    else
    {
        int ans = 0;
        ans = task(w[u]) - task(w[f1]-1); // 搞清先后
        ans += ask(fa[f1], v);
        return ans;
    }
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i < n; ++i)
    {
        int x, y; scanf("%d%d", &x, &y);
        if (x > y) swap(x, y);
        bnum++; next[bnum] = p[x]; p[x] = bnum; v[bnum] = y;
    }
    dfs_1(1, 0); dfs_2(1, 1);
    for (int i = 2; i <= n; ++i) add(w[i], 1);
    scanf("%d", &m); m = m+n-1;
    for (int i = 1; i <= m; ++i)
    {
        char s[2]; scanf("%s", s);
        if (s[0] == ‘A‘)
        {
            int x, y; scanf("%d%d", &x, &y);
            if (x > y) swap(x, y);
            add(w[y], -1);
        }
        else
        {
            int x; scanf("%d", &x);
            printf("%d\n", ask(1, x));
        }
    }
    return 0;
}
时间: 2024-11-06 21:38:51

1103 POI2007 大都市meg的相关文章

bzoj 1103: [POI2007]大都市meg

1103: [POI2007]大都市meg Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了. 不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双 向的土路.从每个村庄都恰好有一条路径到达村庄1(即比特堡).并且,对于每个村庄,它到比特堡的路径恰好 只经过编号比它的编号小的村庄.另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇.在这个未开 化的地方,从来

数据结构(线段树):BZOJ 1103 [POI2007]大都市meg

1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1791  Solved: 925[Submit][Status][Discuss] Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了. 不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双 向的土路.从每个村庄都恰好有一条路径

BZOJ 1103: [POI2007]大都市meg( 树链剖分 )

早上数学考挂了...欲哭无泪啊下午去写半个小时政治然后就又可以来刷题了.. 树链剖分 , 为什么跑得这么慢... --------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #define rep( i , n ) for( int

【BZOJ】1103: [POI2007]大都市meg

http://www.lydsy.com/JudgeOnline/problem.php?id=1103 题意:一棵n节点的树(1<=n<=250000),m条边(1<=m<=250000-1),权值为1,有n+m-1个操作:操作W u:询问u到根的权值和: 操作A u v,将边(u, v)的权值减去1 #include <bits/stdc++.h> using namespace std; const int N=250005; int n, ihead[N], c

BZOJ:1103: [POI2007]大都市meg

题解: 维护x到1的土路条数: 修改一条边相当于修改一个区间: 用树状数组差分实现 对某一个点的贡献相当于求前缀和: 实际上我维护的是公路条数,本质一样 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=300000; const int inf=1000000000; int n,m; int cntedge; int head[maxn]

【BZOJ 1103】 [POI2007]大都市meg

1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1292  Solved: 660 [Submit][Status] Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双向的土路.从每个村庄都恰好有一条路径到达村庄1(即比特

[bzoj1103][POI2007]大都市meg(树状数组+dfs序)

1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2031  Solved: 1069[Submit][Status][Discuss] Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双向的土路.从每个村庄都恰好有一条路径到

bzoj1103[POI2007]大都市meg

bzoj1103[POI2007]大都市meg 题意: 一个n点树,根节点为1,初始时全部边为土路,共n-m+1次操作,每次可将一条边改为公路或求根节点到某个节点要几个多少土路.n,m≤250000 题解: 先求出DFS序,进入节点在时间点的权值为1,离开节点在时间点的权值为-1,如果把公路转成土路就将这条边的左端点的进入时间权值和离开时间权值都置为0,如果询问则输出节点进入时间前缀和.求前缀和及修改的操作可以用树状数组维护. 代码: 1 #include <cstdio> 2 #includ

【POI2007】【Bzoj 1103】大都市meg

http://www.lydsy.com/JudgeOnline/problem.php?id=1103 在线查询某点到根节点的点权和,参考DFS序&欧拉序列,用树状数组维护即可O(nlogn) // <meg.cpp> - Sun Oct 2 08:13:38 2016 // This file is made by YJinpeng,created by XuYike's black technology automatically. // Copyright (C) 2016 C