【Hihocoder 1167】 高等理論電腦科學 (樹鏈的交,線段樹或樹狀數組維護區間和)

來源:互聯網
上載者:User

標籤:樹狀數組   lock   play   open   題解   比較   src   limit   電腦科學   

【題意】

時間限制:20000ms單點時限:1000ms記憶體限制:256MB描述

少女幽香這幾天正在學習高等理論電腦科學,然而她什麼也沒有學會,非常痛苦。所以她出去晃了一晃,做起了一些沒什麼意義的事情來放鬆自己。
門前有一顆n個節點樹,幽香發現這個樹上有n個小精靈。然而這些小精靈都比較害羞,只會在一條特定的路徑上活動。第i個小精靈會在ai到bi的路徑上活動。
兩個小精靈是朋友,若且唯若它們的路徑是有公用點的。
於是幽香想要知道,有多少對小精靈a和b,a和b是朋友呢?其中a不等於b,a,b和b,a看做一對。

輸入

第一行n和P (1 <= n, P <=100000),表示樹的大小和小精靈的個數。樹的節點從1到n標號。
接下來n-1行,每行兩個數a,b,表示a到b之間有一條邊。
接下來P行,第i行兩個數ai,bi,表示小精靈i的活動範圍是ai到bi,其中ai不等於bi。

輸出

一行答案,表示對數。

範例輸入
6 31 22 32 44 54 61 31 55 6
範例輸出
2

 

 

【分析】

   ORZ 。。。

   我好蠢。。一直想樹剖以及線段的交。。。【並且不是線段

  大神題解here:

  兩條樹鏈相交,若且唯若一條樹鏈的lca在另一條樹鏈上,對於每個樹鏈,統計有多少個樹鏈的lca在被他包含,有時兩條樹鏈互相滿足這個條件,但僅僅當這兩條樹鏈的lca相等時才會有,所以特判一下


  上面說得很清楚了,區間的和維護用樹狀數組就可以了。

 

  1 #include<cstdio>  2 #include<cstdlib>  3 #include<cstring>  4 #include<iostream>  5 #include<algorithm>  6 #include<cmath>  7 using namespace std;  8 #define Maxn 100010  9 #define LL long long 10  11 struct node 12 { 13     int x,y,next; 14 }t[Maxn*2];int len; 15  16 int first[Maxn],px[Maxn],py[Maxn]; 17  18 void ins(int x,int y) 19 { 20     t[++len].x=x;t[len].y=y; 21     t[len].next=first[x];first[x]=len; 22 } 23  24 int son[Maxn],dfn[Maxn],sm[Maxn],dep[Maxn],fa[Maxn]; 25 void dfs1(int x,int f) 26 { 27     sm[x]=1;son[x]=0;dep[x]=dep[f]+1;fa[x]=f; 28     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f) 29     { 30         int y=t[i].y; 31         dfs1(y,x); 32         sm[x]+=sm[y]; 33         if(sm[y]>sm[son[x]]) son[x]=y; 34     } 35 } 36  37 int tp[Maxn],cnt; 38 void dfs2(int x,int f,int tpp) 39 { 40     dfn[x]=++cnt;tp[x]=tpp; 41     if(son[x]) dfs2(son[x],x,tpp); 42     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f&&t[i].y!=son[x]) 43      dfs2(t[i].y,x,t[i].y); 44 } 45  46 int c[Maxn],n; 47 bool lca[Maxn]; 48  49 void add(int x,int y) 50 { 51     for(int i=x;i<=n;i+=i&(-i)) 52         c[i]+=y; 53 } 54  55 int query(int l,int r) 56 { 57     int ans=0; 58     for(int i=r;i>=1;i-=i&(-i)) 59         ans+=c[i]; 60     l--; 61     for(int i=l;i>=1;i-=i&(-i)) 62         ans-=c[i]; 63     return ans; 64 } 65  66 int gans(int x,int y,int p) 67 { 68     int ans=0,tt; 69     while(tp[x]!=tp[y]) 70     { 71         if(dep[tp[x]]<dep[tp[y]]) tt=x,x=y,y=tt; 72         if(p==1) ans+=query(dfn[tp[x]],dfn[x]); 73         x=fa[tp[x]]; 74     } 75     if(dep[x]<dep[y]) tt=x,x=y,y=tt; 76     if(p==1) 77     { 78         ans+=query(dfn[y],dfn[x]); 79         return ans; 80     } 81     else return y; 82 } 83  84 int main()     85 { 86     int p; 87     LL ans=0; 88     scanf("%d%d",&n,&p); 89     len=0; 90     memset(first,0,sizeof(first)); 91     for(int i=1;i<n;i++) 92     { 93         int x,y; 94         scanf("%d%d",&x,&y); 95         ins(x,y);ins(y,x); 96     } 97     for(int i=1;i<=p;i++) scanf("%d%d",&px[i],&py[i]); 98     sm[0]=0;dep[0]=0; 99     dfs1(1,0);cnt=0;100     dfs2(1,0,1);101     memset(c,0,sizeof(c));102     memset(lca,0,sizeof(lca));103     for(int i=1;i<=p;i++)104     {105         int x=gans(px[i],py[i],0);106         lca[x]=1;107         add(dfn[x],1);108     }109     for(int i=1;i<=p;i++)110     {111         int x=gans(px[i],py[i],1);112         ans+=x;113     }114     for(int i=1;i<=n;i++) if(lca[i])115     {116         int x=query(dfn[i],dfn[i]);117         ans-=x*(x-1)/2+x;118     }119     printf("%lld\n",ans);120     return 0;121 }
View Code

 

 

2016-11-10 18:17:12

 

【Hihocoder 1167】 高等理論電腦科學 (樹鏈的交,線段樹或樹狀數組維護區間和)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.