zoukankan      html  css  js  c++  java
  • bzoj3631树链剖分

    虽然是水题1A的感觉太爽了O(∩_∩)O~

    题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值

    本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查

    前缀和不要怂!!!

    结果,,,change的长度让人怀疑写change的必要,,,mdzz懒得改了

    1 inline void change(int x,int y){a[x]++;a[y+1]--;}

    这道题注意要点:

    每次都按照顺序加权值的话会导致多算端点的权值,解决方法很简单:算完以后把除出发点以外的所有点权值-1(因为题目保证了遍历每个点,所以除出发点以外每个点肯定被多算一次)

    树链剖分好久没写了,主要部分没问题,就是关于高度的东西写成鬼畜了,没记住高度小的排在前面,导致调了几分钟样例

     1 #include <cstdio>
     2 int n,m=0,N=0,p,q;
     3 int to[600001],nex[600001],son[300001],bro[300001];
     4 int fir[300001],size[300001],pos[300001],top[300001],h[300001],fa[300001];
     5 int l[300001],a[300001],ans[300001],b[300001];
     6 inline void add(int x,int y){to[++m]=y;nex[m]=fir[x];fir[x]=m;}
     7 inline void change(int x,int y){a[x]++;a[y+1]--;}
     8 inline void swap(int &x,int &y){int t=x;x=y;y=t;}
     9 int build(int now,int fat)
    10 {
    11     size[now]=1;h[now]=h[fat]+1;fa[now]=fat;
    12     for(int i=fir[now];i;i=nex[i])
    13     if(to[i]!=fat)
    14         bro[to[i]]=son[now],son[now]=to[i],size[now]+=build(to[i],now);
    15     return size[now];
    16 }
    17 void pou(int now,int to)
    18 {
    19     l[++N]=now;pos[now]=N;top[now]=to;
    20     int max=son[now];
    21     if(!max) return;
    22     for(int i=bro[max];i;i=bro[i])
    23     if(size[i]>size[max]) max=i;
    24     pou(max,to);
    25     for(int i=son[now];i;i=bro[i])
    26     if(i!=max) pou(i,i);
    27 }
    28 void work(int x,int y)
    29 {
    30     while(top[x]!=top[y])
    31     {
    32         if(h[top[x]]<h[top[y]]) swap(x,y);
    33         change(pos[top[x]],pos[x]);
    34         x=fa[top[x]];
    35     }
    36     if(h[x]>h[y]) swap(x,y);
    37     change(pos[x],pos[y]);
    38 }
    39 int main()
    40 {
    41     scanf("%d",&n);
    42     for(int i=1;i<=n;i++)
    43         scanf("%d",&b[i]);
    44     for(int i=1;i<n;i++)
    45         scanf("%d%d",&p,&q),add(p,q),add(q,p);
    46     build(1,0);
    47     pou(1,1);
    48     for(int i=1;i<n;i++)
    49         work(b[i],b[i+1]);
    50     for(int i=1;i<=n;i++)
    51         ans[l[i]]=ans[l[i-1]]+a[i];
    52     for(int i=1;i<=n;i++)
    53         printf("%d
    ",ans[i]-1+(i==b[1]));
    54 } 
  • 相关阅读:
    程序员数学
    [topcoder]FlowerGarden
    [leetcode]Trapping Rain Water
    [leetcode]Gray Code
    [leetcode]Unique Paths II
    hdu 4112 Break the Chocolate(ceil floor)
    【转】博弈-翻硬币游戏
    POJ 3710 Christmas Game
    hdu 3590 PP and QQ
    博弈进阶
  • 原文地址:https://www.cnblogs.com/wanglichao/p/5788268.html
Copyright © 2011-2022 走看看