zoukankan      html  css  js  c++  java
  • 【JLOI2014】松鼠的新家

    这道题洛谷给的标签是LCA,线段树,树链剖分。

    当然LCA+树上差分能通过这道题,但出现在树链剖分当中,我决定用树链剖分解决

    显然这是一道裸的树链剖分。树剖之后进行区间修改,单点查询操作。(这道题线段树都不用build……23333)

    我们按照题目给的顺序给这一棵"树"放上糖果,当然注意重复的部分要减掉,最后对每一个点进行查询即可。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 typedef long long ll;
      5 #define N 300010
      6 inline int read() {
      7     int ret=0,f=1;
      8     char c=getchar();
      9     while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
     10     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
     11     return ret*f;
     12 }
     13 using namespace std;
     14 int n;
     15 struct edge {
     16     int next,to;
     17 }a[N<<1];
     18 int num,head[N<<1];
     19 int fa[N],son[N],top[N],d[N],seg[N],rev[N],tot;
     20 int sum[N<<2],tag[N<<2],size[N];
     21 int turn[N];
     22 inline void add(int from,int to) {
     23     a[++num].next=head[from]; a[num].to=to; head[from]=num;
     24     swap(from,to);
     25     a[++num].next=head[from]; a[num].to=to; head[from]=num;
     26 }
     27 void dfs1(int u,int f) {
     28     size[u]=1;
     29     fa[u]=f;
     30     d[u]=d[f]+1;
     31     for(int i=head[u];i;i=a[i].next) {
     32         int v=a[i].to;
     33         if(v==f) continue ;
     34         dfs1(v,u);
     35         size[u]+=size[v];
     36         if(size[v]>size[son[u]]) son[u]=v;
     37     }
     38 }
     39 void dfs2(int u,int f) {
     40     if(son[u]) {
     41         seg[son[u]]=++tot;
     42         rev[tot]=son[u];
     43         top[son[u]]=top[u];
     44         dfs2(son[u],u);
     45     }
     46     for(int i=head[u];i;i=a[i].next) {
     47         int v=a[i].to;
     48         if(!top[v]) {
     49             seg[v]=++tot;
     50             rev[tot]=v;
     51             top[v]=v;
     52             dfs2(v,u);
     53         }
     54     }
     55 }
     56 inline void pushdown(int now,int len) {
     57     if(!tag[now]) return ;
     58     tag[now<<1]+=tag[now];
     59     tag[now<<1|1]+=tag[now];
     60     sum[now<<1]+=tag[now]*(len-(len>>1));
     61     sum[now<<1|1]+=tag[now]*(len>>1);
     62     tag[now]=0;
     63 }
     64 void updata(int now,int l,int r,int x,int y,int v) {
     65     if(x<=l&&r<=y) {
     66         tag[now]+=v;
     67         sum[now]+=v*(r-l+1);
     68         return ;
     69     }
     70     int mid=l+r>>1;
     71     pushdown(now,r-l+1);
     72     if(x<=mid) updata(now<<1,l,mid,x,y,v);
     73     if(y>mid) updata(now<<1|1,mid+1,r,x,y,v);
     74     sum[now]=sum[now<<1]+sum[now<<1|1];
     75 }
     76 void find(int x,int y) {
     77     while(top[x]!=top[y]) {
     78         if(d[top[x]]<d[top[y]]) swap(x,y);
     79         updata(1,1,tot,seg[top[x]],seg[x],1);
     80         x=fa[top[x]];    
     81     }
     82     if(d[x]>d[y]) swap(x,y);
     83     updata(1,1,tot,seg[x],seg[y],1);
     84 }
     85 int query(int now,int l,int r,int x) {
     86     if(l==r) return sum[now];
     87     int mid=l+r>>1;
     88     pushdown(now,r-l+1);
     89     if(x<=mid) return query(now<<1,l,mid,x);
     90     else return query(now<<1|1,mid+1,r,x);
     91 }
     92 int main() {
     93     n=read();
     94     for(int i=1;i<=n;i++) turn[i]=read();
     95     for(int i=1;i<n;i++) add(read(),read());
     96     dfs1(1,0);
     97     tot=seg[1]=rev[1]=top[1]=1;
     98     dfs2(1,0);
     99 //    build(1,1,tot);
    100     for(int i=1;i<n;i++) {
    101         find(turn[i],turn[i+1]);
    102         updata(1,1,tot,seg[turn[i+1]],seg[turn[i+1]],-1);
    103     }
    104     for(int i=1;i<=n;i++) {
    105         printf("%d
    ",query(1,1,tot,seg[i]));
    106     }
    107     return 0;
    108 }
    AC Code
  • 相关阅读:
    计算1的个数
    【环境配置】配置git
    Spoj 9887 Binomial coefficients 构造
    程序猿与HR博弈之:有城府的表达你的兴趣爱好
    C和指针 (pointers on C)——第六章:指针(上)
    关于undo表空间配置错误的ORA-30012
    每天进步一点点——Linux系统中的异常堆栈跟踪简单实现
    javaScript 对象的使用
    手机游戏加密那点事儿_2d资源加密_1
    支持向量机
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10542508.html
Copyright © 2011-2022 走看看