BZOJ 1103 大都市

dfs序+BIT。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 250050
#define maxe 500500
using namespace std;
int n,x,y,m,g[maxv],nume=0,w[maxv],mx[maxv],dis[maxv],val[maxv],fath[maxv],times=0;
char s[5];
struct edge
{
    int v,nxt;
}e[maxe];
int lowbit(int x)
{
    return (x&(-x));
}
void addedge(int u,int v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void dfs(int x)
{
    w[x]=mx[x]=++times;
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (v!=fath[x])
        {
            dis[v]=dis[x]+1;fath[v]=x;
            dfs(v);
            mx[x]=max(mx[x],mx[v]);
        }
    }
}
void add(int pos,int x)
{
    for (int i=pos;i<=n+1;i+=lowbit(i))
        val[i]+=x;
}
void modify()
{
    scanf("%d%d",&x,&y);
    if (dis[x]>dis[y]) swap(x,y);
    add(w[y],1);add(mx[y]+1,-1);
}
void ask()
{
    scanf("%d",&x);int regis=x;x=w[x];
    int ret=0;
    while (x)
    {
        ret+=val[x];
        x-=lowbit(x);
    }
    printf("%d\n",dis[regis]-ret);
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&x,&y);
        addedge(x,y);addedge(y,x);
    }
    dfs(1);
    scanf("%d",&m);
    for (int i=1;i<=n+m-1;i++)
    {
        scanf("%s",s);
        if (s[0]==‘A‘) modify();
        else ask();
    }
    return 0;
}
时间: 2024-11-05 11:36:20

BZOJ 1103 大都市的相关文章

BZOJ 1103 大都市(dfs序+树状数组)

应该是一道很水的题吧... 显然可以用树链剖分解决这个问题,虽然不知道多一个log会不会T.但是由于问题的特殊性. 每次修改都是将边权为1的边修改为0,且询问的是点i到根节点的路径长度. 令点i到根节点的路径长度为w[i],显然初始时w[i]=dep[i].考虑修改边为(u,v),那么令u为深度大的点. 那么u的子树的所有答案就要减1.考虑dfs序,则每次需要修改的是一段连续的区间. 树状数组维护单点查询,区间修改,美滋滋. # include <cstdio> # include <c

【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(即比特

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][POI 2007]大都市(DFS求拓扑序+树状数组)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1103 题目大意:给你一个树,刚开始所有树边边权均为1,不断地将其中的某些边边权改为0,其间问你某个点到根节点之间路径上的边权和. 此题和POJ的Apple Tree很相近... 首先DFS生成整棵树的拓扑序,DFS时每个结点i进入的时间l[i]和离开的时间r[i],然后对每次更改操作,维护树状数组即可. #include <iostream> #include <stdi

【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

BZOJ 1103 POI 2007 大都市meg 树状数组

题目大意:给出一棵树,一开始每两个点之间都是由土路连接的,但是会有一些土路逐渐变成公路,问每次从点1开始到点k有多少土路. 思路:POI不怎么难的题,实际上每个点到1的土路的数量就是这个点的深度,在土路变成公路的时候,这个点以及子树的所有节点的深度都要-1,子树修改就很基本了,可以用DFS序+fenwick,当然要是不嫌麻烦也可以树链剖分,但是常数会比较卡.. CODE: #include <cstdio> #include <cstring> #include <iostr

bzoj 1103

题目大意:有一棵树根为1,刚开始每条边的权值为1,  现在有m + n - 1 个操作, A :x  y  , 将x和y相连的边权值变为1, W:x, 询问x到1路径上的权值和. 思路 : 方法一: 用dfs序建立树状数组, 每个点入栈位置的值为1, 出栈为-1, 询问的值就是sum( l [ x ] ), 修改就将出栈,入栈的点全部变成1, 巧妙的地方在于 利用dfs序求前缀和会把不是在这条链上的边全部抵消掉. 方法二:用dfs序建立线段数, 线段数里每个点表示该点到1的权值和, 修改一条边相