JZOJ6258 省選模擬8 9 轟炸

2022-05-31 21:57:10 字數 2059 閱讀 3896

給你一棵樹和樹上的許多條從後代到祖先的鏈,選擇每條鏈需要一定代價,問覆蓋整棵樹的所有點的最小代價是多少。

\(n,m\leq 100000\)

(由於時間過於久遠,所以直接說正解算了)

對於這樣的題,顯然有一種暴力的dp做法。

設\(f_\)表示\(i\)子樹全部被覆蓋,其中伸出來的一條鏈到達深度為\(j\)的祖先時的最小代價。

轉移不在此贅述。

然後可以線段樹優化。

有兩種情況:從\(i\)子樹伸出來的鏈是最高的;從\(i\)伸出來的鏈是最高的。

我們欽定某一條鏈是最高的,不用管是否存在其他的鏈高過它的情況,因為如果有那樣的情況,那麼這個狀態的答案就會被覆蓋掉。

首先記錄一下每個子樹的最優答案之和,記作\(sum\)。

枚舉子樹,對於它的所有狀態加上\(sum\),減去它本身的最優答案。也就是將其它子樹的答案之和給它加上。對於自己,就直接用\(sum\)加上所選擇的鏈的代價。

然後線段樹合併即可。

using namespace std;

#include #include #include #include #define n 300010

#define inf 1000000000000000000

int n,m;

struct edge e[n*2];

int ne;

edge *last[n];

int dep[n];

struct edge2 e2[n*2];

int ne2;

edge2 *last2[n];

struct node

inline void update()

} d[n*30],*null;

int cnt;

inline node *newnode());}

node *root[n];

void change(node *t,int l,int r,int x,long long c)

t->pushdown();

int mid=l+r>>1;

if (x<=mid)

change(t->l==null?t->l=newnode():t->l,l,mid,x,c);

else

change(t->r==null?t->r=newnode():t->r,mid+1,r,x,c);

t->update();

}void cut(node *t,int l,int r,int en)

else

cut(t->r,mid+1,r,en);

t->update();

}node *merge(node *a,node *b,int l,int r,long long plus,int en)

a->pushdown(),b->pushdown();

int mid=l+r>>1;

a->l=merge(a->l,b->l,l,mid,plus,en);

if (midr=merge(a->r,b->r,mid+1,r,plus,en);

else

a->r=null;

a->update();

return a;

}bool dfs(int x,int fa)

node *un=newnode();

for (edge *ei=last[x];ei;ei=ei->las)

if (ei->to!=fa)

un=merge(un,root[ei->to],1,n,sum-root[ei->to]->mn,x==1?1:dep[x]-1);

for (edge2 *ei=last2[x];ei;ei=ei->las)

change(un,1,n,dep[ei->to],ei->w+sum);

root[x]=un;

return root[x]->mn>=inf;

}int main()

for (int i=1;imn);

return 0;

}

這種樹上dp的東西很多時候都可以揹包啊……

JZOJ6258 省選模擬8 9 轟炸

給你一棵樹和樹上的許多條從後代到祖先的鏈,選擇每條鏈需要一定代價,問覆蓋整棵樹的所有點的最小代價是多少。n m 100000 n,m leq 100000 n,m 10 0000 由於時間過於久遠,所以直接說正解算了 對於這樣的題,顯然有一種暴力的dp做法。設f i,jf fi,j 表示i ii子樹...

JZOJ6257 省選模擬8 9 修路

有一堆點,每個點都有其權值c ic i ci 每次插入邊 u,v u,v u,v u uu和1 11連通,v vv和1 11不連通。最後保證形成一棵樹。每次插入的時候詢問1 11到u uu的路徑上逆序對的個數。然後將1 11到u uu的路徑上的所有節點的權值設為c vc v cv 一看就知道是什麼資...

JZOJ 省選模擬 string

一行乙個整數表示答案。sample input 樣例輸入 3 3sample output 樣例輸出 首先我們忽略重複的字串,定義 n 表示長度為 n 的回文串,或由兩個回文串拼成的字串數量。那麼可以通過列舉第乙個回文串的長度 可以為 0 可以算出f n 但是正如剛才所說,會對如 abaaba 這樣...