日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【启智树NOIP模拟】生存【父子分治】

發布時間:2023/12/3 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【启智树NOIP模拟】生存【父子分治】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:有 nnn 個城市連成一棵樹,每個城市有 aia_iai? 個人。接下來 mmm 天每天會發生 kik_iki? 次災難,每個災難會讓一個給定城市的人全部死掉。每個人一天可以走一條邊,也可以不動。求最多多少人能活過這 mmm 天。

n≤106,∑ki≤2×106n\leq 10^6,\sum k_i\leq 2\times 10^6n106,ki?2×106

倒過來考慮,維護在哪些位置的人可以活到最后,相當于要支持以下操作

  • 把一個點染黑。
  • 所有白點擴展 111 步。
  • 對于 222 操作,一個黑點會變白當且僅當和一個原來的白點相鄰。考慮分別維護這個白點是父親還是兒子。

    需要維護的東西:

    huh_uhu? 表示真實情況下 uuu 的白兒子個數。

    nnn 個 vector 記錄每個點 可能 需要被自己更新為白點的所有黑兒子。

    封裝兩個線性結構 q,sqq,sqq,sq ,記錄可能會被兒子更新為白點的結點、可能會用來更新黑兒子的結點。

    染黑的時候,自己進 qqq,父親進 sqsqsq,更新父親的 hhh 和 vector。

    然后這一天的行動,把 qqqsqsqsq 一個個取出來判斷是否合法并更新自己或 vector 中的兒子,需要染白的記下來稍后處理。

    染白的時候,自己進 sqsqsq,父親進 qqq,更新父親的 hhh。因為這里更新不了 vector,只能不刪,所以不能用 vector 的大小來代替 hhh

    復雜度 O(n+m+∑ki)O(n+m+\sum k_i)O(n+m+ki?)

    #include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <vector> #define MAXN 1000005 using namespace std; inline int read() {int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans; } typedef long long ll; vector<int> e[MAXN],lis[MAXN],son[MAXN]; int a[MAXN],col[MAXN],fa[MAXN],h[MAXN]; struct que {int a[MAXN],vis[MAXN],cnt;inline void push(int x){if (!vis[x]) vis[a[++cnt]=x]=1;}inline int pop(){if (cnt) return vis[a[cnt]]=0,a[cnt--];return 0;} }q,sq,ans; void dfs(int u,int f){fa[u]=f;for (int i=0;i<(int)e[u].size();i++) if (e[u][i]!=f) ++h[u],dfs(e[u][i],u);} inline void die(int u) {if (col[u]) return;col[u]=1;q.push(u);if (fa[u]){son[fa[u]].push_back(u),--h[fa[u]];sq.push(fa[u]);} } inline void live(int u) {if (!col[u]) return;col[u]=0,sq.push(u);if (fa[u]) ++h[fa[u]],q.push(fa[u]); } int main() {int n,m;n=read(),m=read();for (int i=1;i<=n;i++) a[i]=read();for (int i=1;i<n;i++){int u,v;u=read(),v=read();e[u].push_back(v),e[v].push_back(u);}dfs(1,0);for (int i=1;i<=m;i++){lis[i].resize(read());for (int j=0;j<(int)lis[i].size();j++) lis[i][j]=read();}for (int T=m;T>=1;T--){for (int i=0;i<(int)lis[T].size();i++) die(lis[T][i]);for (int u=q.pop();u;u=q.pop()) if (h[u]) ans.push(u);for (int u=sq.pop();u;u=sq.pop()) if (!col[u]){for (int i=0;i<(int)son[u].size();i++)ans.push(son[u][i]);son[u].clear(); }for (int u=ans.pop();u;u=ans.pop()) live(u);}ll ans=0;for (int i=1;i<=n;i++) if (!col[i]) ans+=a[i];cout<<ans;return 0; }

    總結

    以上是生活随笔為你收集整理的【启智树NOIP模拟】生存【父子分治】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。