zoukankan      html  css  js  c++  java
  • hihoCoder 1145 幻想乡的日常(树状数组 + 离线处理)

    http://hihocoder.com/problemset/problem/1145?sid=1244164

    题意:

    幻想乡一共有n处居所,编号从1到n。这些居所被n-1条边连起来,形成了一个树形的结构。

    每处居所都居住着一个小精灵。每天小精灵们都会选出一个区间[l,r],居所编号在这个区间内的小精灵一起来完成一项任务。

    特别的,居所相邻的(有边相连的)两个小精灵会自发的组成一队,并且如果a和b相邻b和c相邻,那么a和c也在同一队里面。每天的任务完成之后,队伍就会解散;第二天再根据新的区间组成新的队伍。

    给出每天小精灵们选出的区间,你知道每天组成的队伍数量吗?

    思路:
    越来越觉得树状数组在处理区间问题上真的很强。

    将询问按右坐标排序,将顶点按从小到大的顺序看它的子节点是否可以插入。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn = 100000+5;
     7 
     8 int tot,n,m;
     9 int head[maxn],c[maxn],ans[maxn];
    10 
    11 struct node
    12 {
    13     int v,next;
    14 }e[2*maxn];
    15 
    16 struct Node
    17 {
    18     int l,r,id;
    19     bool operator< (const Node& rhs) const
    20     {
    21         return r<rhs.r;
    22     }
    23 }query[maxn];
    24 
    25 void addEdge(int u, int v)
    26 {
    27     e[tot].v = v;
    28     e[tot].next = head[u];
    29     head[u] = tot++;
    30 }
    31 
    32 int lowbit(int x)
    33 {
    34     return x&-x;
    35 }
    36 
    37 int sum(int x)
    38 {
    39     int ret = 0;
    40     while(x>0)
    41     {
    42         ret += c[x];
    43         x -= lowbit(x);
    44     }
    45     return ret;
    46 }
    47 
    48 int add(int x)
    49 {
    50     while(x<=n)
    51     {
    52         c[x] += 1;
    53         x +=lowbit(x);
    54     }
    55 }
    56 
    57 int main()
    58 {
    59     //freopen("in.txt","r",stdin);
    60     scanf("%d%d",&n,&m);
    61     tot = 0;
    62     memset(head,-1,sizeof(head));
    63     for(int i=0;i<n-1;i++)
    64     {
    65         int u,v;
    66         scanf("%d%d",&u,&v);
    67         addEdge(u,v);
    68         addEdge(v,u);
    69     }
    70     for(int i=0;i<m;i++)
    71     {
    72         scanf("%d%d",&query[i].l,&query[i].r);
    73         query[i].id = i;
    74     }
    75     int pos = 0;
    76     sort(query,query+m);
    77     for(int u=1;u<=n;u++)
    78     {
    79         for(int i=head[u];i!=-1;i=e[i].next)
    80             if(e[i].v<u)  add(e[i].v);
    81         while(u==query[pos].r && pos<m)
    82         {
    83             ans[query[pos].id] = query[pos].r-query[pos].l+1-(sum(u)-sum(query[pos].l-1));
    84             pos++;
    85         }
    86     }
    87     for(int i=0;i<m;i++)
    88         printf("%d
    ",ans[i]);
    89     return 0;
    90 }
  • 相关阅读:
    UVa 439,Knight Moves
    UVa127,"Accordian" Patience
    UVa11882,Biggest Number
    UVa1599,Ideal Path
    我什么时候才能脱离题解....
    UVa208,Firetruck
    UVa1600,Patrol Robot
    UVa12325, Zombie's Treasure Chest
    随笔
    UVa11054
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7977475.html
Copyright © 2011-2022 走看看