zoukankan      html  css  js  c++  java
  • BZOJ 3631: [JLOI2014]松鼠的新家

       太好了,第一次交就AC了,第一次这么顺利,这是一道树链剖分的题,比较容易吧!加油,相信自己,能行的。

      不过还是有点慢,跑了1900多毫秒。

      1 #include<cstdio>
      2 #include<iostream>
      3 #define rep(i,j,k) for(int i = j; i <= k; i++)
      4 #define maxn 300005
      5 using namespace std;
      6 int shun[maxn];
      7  
      8 struct node{
      9 int addv, l, r;
     10 node() {
     11    addv = l = r = 0;
     12 }
     13 } nod[maxn*4];
     14  
     15 struct edge{
     16 int to;
     17 edge* next;
     18 };
     19 edge *head[maxn], edges[maxn*2], *pt; 
     20  
     21 void add_edge(int x,int y)
     22 {
     23     pt->to = x, pt->next = head[y], head[y] = pt++;
     24     pt->to = y, pt->next = head[x], head[x] = pt++;
     25 }
     26  
     27 int read()
     28 {
     29     int s = 0, t = 1; char c = getchar();
     30     while( !isdigit(c) ){
     31         if( c == '-' ) t = -1; c = getchar();
     32     }
     33     while( isdigit(c) ){
     34         s = s * 10 + c - '0'; c = getchar();
     35     }
     36     return s * t;
     37 }
     38 int pa[maxn], top[maxn], dep[maxn], size[maxn], son[maxn];
     39 int w[maxn], tot = 0;
     40  
     41 void dfs(int now)
     42 {
     43     size[now] = 1, son[now] = 0;
     44     for(edge* i = head[now]; i; i = i->next){
     45         int to = i->to; if( to == pa[now] ) continue;
     46         pa[to] = now, dep[to] = dep[now] + 1;
     47         dfs(to); size[now] += size[to];
     48         if( size[to] > size[son[now]] ) son[now] = to;
     49     }
     50 }
     51  
     52 void dfs2(int now,int ph)
     53 {
     54     top[now] = ph, w[now] = ++tot;
     55     if( son[now] ) dfs2(son[now],ph);
     56     for(edge*i = head[now]; i; i = i->next){
     57         int to = i->to; if( to == pa[now] || to == son[now] ) continue;
     58         dfs2(to,to);
     59     } 
     60 } 
     61  
     62 void yuchu(int l,int r,int num)
     63 {
     64     nod[num].l = l, nod[num].r = r;
     65     if( l == r ){
     66         if( w[shun[1]] != l ) nod[num].addv = -1;
     67         return;
     68     }
     69     int mid = (l+r) / 2;
     70     yuchu(l,mid,num*2);
     71     yuchu(mid+1,r,num*2+1);
     72 }
     73  
     74 void update(int l,int r,int num)
     75 {
     76     int ll = nod[num].l, rr = nod[num].r;
     77     if( ll >= l && r >= rr ){
     78         nod[num].addv += 1;
     79         return ;
     80     }
     81     int mid = (ll+rr) / 2;
     82     if( r <= mid ) update(l,r,num*2);
     83     else if( l > mid ) update(l,r,num*2+1);
     84     else update(l,mid,num*2), update(mid+1,r,num*2+1);
     85 }
     86  
     87 void add(int x,int y)
     88 {
     89     while( top[x] != top[y] ){
     90         if( dep[top[x]] < dep[top[y]] ){
     91             swap(x,y);
     92         }
     93         update(w[top[x]],w[x],1);
     94         x = pa[top[x]];
     95     }
     96     if( dep[x] > dep[y] ) swap(x,y);
     97     update(w[x],w[y],1);
     98 }
     99  
    100 void main_tain(int num)
    101 {
    102     if( !nod[num].addv ) return;
    103     nod[num*2].addv += nod[num].addv;
    104     nod[num*2+1].addv += nod[num].addv;
    105 }
    106  
    107 void push(int num)
    108 {
    109     int l = nod[num].l, r = nod[num].r;
    110     if( l == r ) {
    111         w[shun[l]] = nod[num].addv;
    112         return;
    113     }
    114     main_tain(num);
    115     push(num*2), push(num*2+1);
    116 }
    117  
    118 int main()
    119 {
    120     int n = read();
    121     rep(i,1,n) shun[i] = read();
    122     pt = edges;
    123     rep(i,1,n-1){
    124         int x = read(), y = read();
    125         add_edge(x,y);
    126     }
    127     dep[1] = 1;
    128     dfs(1);
    129     dfs2(1,1);
    130     yuchu(1,tot,1);
    131     rep(i,2,n){
    132         add(shun[i-1],shun[i]);
    133     }
    134     rep(i,1,n) shun[w[i]] = i;
    135     push(1);
    136     rep(i,1,n){
    137         printf("%d
    ", w[i]);
    138     }
    139     return 0;
    140 }

    3631: [JLOI2014]松鼠的新家

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 991  Solved: 489
    [Submit][Status][Discuss]

    Description

    松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。
    可是这样会导致**重复走很多房间,懒惰的**不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。**是个馋家伙,立马就答应了。
    现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。

    Input

    第一行一个整数n,表示房间个数
    第二行n个整数,依次描述a1-an
    接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

    Output

    一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让**有糖果吃。

    Sample Input

    5
    1 4 5 3 2
    1 2
    2 4
    2 3
    4 5

    Sample Output

    1
    2
    1
    2
    1

    HINT

    2<= n <=300000

    人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方
  • 相关阅读:
    看MySQL官方文档的示例SQL有感
    MySQL 主外键约束与标准SQL不同的地方
    pip安装包时遇到的Bug
    MySQL update 语句与标准SQL不同的地方
    让MySQL在美国标准下运行
    mysqlslap 压力测试工具
    django 自动化测试的故障排查
    mysql-8.0.11 比较坑的地方dba门要淡定
    python3 如何给装饰器传递参数
    python3 装饰器应用举例
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5082403.html
Copyright © 2011-2022 走看看