1. 程式人生 > >hdu4358 樹形轉線性 線段樹

hdu4358 樹形轉線性 線段樹

題意:給定了一棵樹和樹上每一個節點的權值 然後詢問是給出子樹頂點求子樹中出現k次的節點權值的個數

解法:把樹形先轉化成線性的 然後離線所有詢問 不要忘了把樹上節點的權值離散化 弄完之後就直接往

掃就可以了  當某一種權值>=k時才進行維護

#pragma comment(linker,"/STACK:102400000,102400000")
#include<cstdio>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
#define maxn 111111
vector<int>g[maxn];
int L[maxn],R[maxn],tot,val[maxn],num[maxn],head[maxn],vis[maxn],n;
void dfs(int u,int f){
    L[u]=++tot;
    num[tot]=val[u];
    for(int i=0;i<g[u].size();++i){
        int v=g[u][i];
        if(v==f)continue;
        dfs(v,u);
    }
    R[u]=tot;
}
struct node{
    int v,l,r,id;
}_q[maxn];
int cmp(node x,node y){return x.r<y.r;}
int add[maxn<<2];
inline void down(int rt){
    if(add[rt]){
        add[ls]+=add[rt],add[rs]+=add[rt];
        add[rt]=0;
    }
}
inline void build(int rt,int l,int r){
    add[rt]=0;if(l==r)return ;
    build(ls,l,mid);
    build(rs,mid+1,r);
}
inline void ins(int rt,int l,int r,int L,int R,int w){
    if(L<=l&&r<=R){add[rt]+=w;return ;}
    down(rt);
    if(L<=mid)ins(ls,l,mid,L,R,w);
    if(mid<R)ins(rs,mid+1,r,L,R,w);
}
inline int query(int rt,int l,int r,int pos){
    if(l==r)return add[rt];
    down(rt);
    if(pos<=mid)return query(ls,l,mid,pos);
    return query(rs,mid+1,r,pos);
}
int x[maxn];
vector<int>pos[maxn];
int ans[maxn];
int main()  {
    int t,_=0,k,u,v,q;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&k);
        tot=0;
        rep(i,1,n){
            scanf("%d",&val[i]),x[i]=val[i];
            g[i].clear(),pos[i].clear();
        }
        rep(i,1,n-1){
            scanf("%d%d",&u,&v);
            g[u].push_back(v),g[v].push_back(u);
        }
        sort(x+1,x+1+n);
        
        int  cnt=(int)(unique(x+1,x+n+1)-x-1);
        for(int i=1;i<=n;i++)val[i]=(int)(lower_bound(x+1,x+cnt+1,val[i])-x);
        
        dfs(1,-1);
        
        scanf("%d",&q);
        rep(i,0,q-1){
            scanf("%d",&_q[i].v);
            _q[i].l=L[_q[i].v];_q[i].r=R[_q[i].v];
            _q[i].id=i;
        }

        sort(_q,_q+q,cmp);build(1,1,tot);
        int cur=0;
        rep(i,1,tot){
            int va=num[i];
            pos[va].push_back(i);
            int sz=(int)pos[va].size();
            if(sz>=k){
                if(sz==k)ins(1,1,tot,1,pos[va][sz-k],1);
                else{
                    ins(1,1,tot,1,pos[va][sz-k-1],-1);
                    ins(1,1,tot,pos[va][sz-k-1]+1,pos[va][sz-k],1);
                }
            }
            while(cur<q&&_q[cur].r==i){
                ans[_q[cur].id]=query(1,1,tot,_q[cur].l);
                ++cur;
            }
        }
        if(_)puts("");
        printf("Case #%d:\n",++_);
        rep(i,0,q-1)printf("%d\n",ans[i]);
    }
    return 0;
}

相關推薦

hdu4358 樹形線性 線段

題意:給定了一棵樹和樹上每一個節點的權值 然後詢問是給出子樹頂點求子樹中出現k次的節點權值的個數 解法:把樹形先轉化成線性的 然後離線所有詢問 不要忘了把樹上節點的權值離散化 弄完之後就直接往 掃就可以了  當某一種權值>=k時才進行維護 #pragma comme

PID 60 線段樹形線性

題意:有一棵樹,開始的時候樹上的每一個節點都沒有打結,實現兩個操作 給樹上的某一個節點及其所有子節點翻轉 即每個打結的節點變成沒有節,沒打結的打結,然後詢問打結的節點的個數在某一棵子樹中的個數 解法:利用線段樹將節點轉化為線性結構,然後對重新標號的線段進行操作即可  #in

[BZOJ4627][BeiJing2016]回壽司(線段)

從左到右處理,設到當前數R的字首和為cnt[i],則以i為右端點的合法的區間左端點j必然是L<=cnt[i]-cnt[j-1]<=R,即cnt[i]-R<=cnt[j-1]<=cnt[i]-L。 問題相當於每次單點在cnt[i]處計數器加1,然後區間詢問[cnt[i]-R,cnt[i

LOJ2537 PKUWC2018 Minimax 樹形DP、線段合併

傳送門 題意:自己去看 首先可以知道,每一個點都有機率被選到,所以$i$與$V_i$的關係是確定了的。 所以我們只需要考慮每一個值的取到的概率。 很容易設計出一個$DP$:設$f_{i,j}$為在第$i$個點取到權值第$j$小的點的概率,轉移就是$f_{i,j}=f_{lson,j} \times

洛谷3783 SDOI2017 天才黑客(最短路+虛+邊點+線段優化建圖)

題目連結 成功又一次自閉了 怕不是豬國殺之後最自閉的一次 一看到最短路徑。 我們就能推測這應該是個最短路題 現在考慮怎麼建圖 根據題目的意思,我們可以發現,在本題中,邊與邊之間存在一些轉換關係,但是點與點之間並不存在。 那麼我們考慮 邊轉點,點轉邊。 每一條邊拆成

Codeforces 671D Roads in Yusland [樹形DP,線段合並]

first 維護 include using int con lld main bits 洛谷 Codeforces 這是一個非正解,被正解暴踩,但它還是過了。 思路 首先很容易想到DP。 設\(dp_{x,i}\)表示\(x\)子樹全部被覆蓋,而且向上恰好延伸到\(d

多叉二叉+樹形dp(codevs 1746 貪吃的九頭龍 2002noi)

main bsp 搜索 我們 bre define div 思考 import 題目傳送門 看到這個題目我們要先把問題簡化了,條件中是多叉樹,我們可以把它轉換成二叉樹,左邊是兒子右邊是兄弟的儲存方式。 首先先判斷否的部分,當總的果子小於需求,也就是N-k<M-1時

線段模版(

odi d+ space track build clu urn ffffff rac //=========================================== //segment tree //final version //by kevin_sam

Codeforces 671D. Roads in Yusland(樹形DP+線段

pla too 不知道 ret 線上 tchar 起點 樹形 ads   調了半天居然還能是線段樹寫錯了,藥丸   這題大概是類似一個樹形DP的東西。設$dp[i]$為修完i這棵子樹的最小代價,假設當前點為$x$,但是轉移的時候我們不知道子節點到底有沒有一條越過$x$的路

【bzoj5123】[Lydsy12月賽]線段的匹配 樹形dp+記憶化搜索

記憶 兩種 spa post mes efi http 搜索 style 題目描述 求一棵 $[1,n]$ 的線段樹的最大匹配數目與方案數。 $n\le 10^{18}$ 題解 樹形dp+記憶化搜索 設 $f[l][r]$ 表示根節點為 $[l,r]$ 的線段

2017 ICPC 西安站現場賽 A.XOR (線段+線性基)

getchar tput 線性 calculate ext following case all pri XORConsider an array A with n elements. Each of its element is A[i] (1 ≤ i ≤ n). Th

UVALive - 8512 線段維護線性基(僅觀賞)

clear main stack best Go etc c++ oid putchar 題意:給定\(a[1...n]\),\(Q\)次詢問求\(A[L...R]\)的異或組合再或上\(K\)的最大值 目前提交處於TLE狀態,原因待查 #include<iostre

[bzoj1812][IOI2006]riv_多叉二叉_樹形dp

lag pri ace 好題 cin eof for flag 需要 riv bzoj-1812 IOI-2006 題目大意:給定一棵n個點樹,要求在上面建立k個收集站。點有點權,邊有邊權,整棵樹的代價是每個點的點權乘以它和它的最近的祖先收集站的距離積的和。 註釋:$1

codeforces CF920F SUM and REPLACE 線段 線性篩約數

arrow 替換 input void set 範圍 HERE lld 數據 $ \Rightarrow $ 戳我進CF原題 F. SUM and REPLACE time limit per test: 2 seconds memory limit per test:

ACM-ICPC 2018 焦作賽區網絡預賽 E. Jiu Yuan Wants to Eat (鏈剖分-線性變換線段)

online top splay 線段樹 clas mes bits amp play 樹鏈剖分若不會的話可自行學習一下. 前兩種操作是線性變換,模\(2^{64}\)可將線段樹全部用unsigned long long 保存,另其自然溢出. 而取反操作比較不能直接處理,因

[LOJ#2473][九省聯考2018]祕密襲擊(樹形DP+生成函式+線段合併+拉格朗日插值)

Address 洛谷P4365 BZOJ5250 LOJ#2473 The First Step - 轉化 簡版題意:給定一棵點帶權樹,求樹上所有大小大於 k

多叉/圖結構維護問題線性結構——dfs序

dfs——深度優先遍歷搜尋 儲存結構:鏈式向前星 下面是我看到的一篇很好的鏈式向前星講解文章: 深度理解鏈式向前星 轉載出處: https://blog.csdn.net/ACdreamers/article/details/16902023 鏈式向前星的邏輯結構如下 dfs的執行程式

BZOJ5123 線段的匹配(樹形dp)

  線段樹的任意一棵子樹都相當於節點數與該子樹相同的線段樹。於是假裝在樹形dp即可,記憶化搜尋實現,有效狀態數是logn級別的。 #include<iostream> #include<cstdio> #include<cmath> #include<cst

線段入門(一)自 WDVXDR

  這篇文章依然是左神(就是那個複賽寫錯YESNO,狂丟60分的帥小夥)所寫,在此轉載,供學弟學妹們膜拜,原文出處:https://www.cnblogs.com/wdvxdr/p/7238253.html。   正文如下:   接觸線段樹前我們先看一道比較

資料結構——第八章:線段(區間)

線段樹(Segment Tree) 內容概覽: 一、什麼是線段樹? 二、線段樹的基礎表示 三、建立線段樹 四、線段樹中的區間查詢 五、LeetCode上線段樹相關的問題 六、線段樹的更新操作 七、線段樹更多相關的問題 為什麼要使用區間樹? 對於給定區間