CodeForces 1228F One Node is Gone

来源:https://www.cnblogs.com/ycx-akioi/archive/2019/10/14/CodeForces-1228F.html
-Advertisement-
Play Games

"洛谷題目頁面傳送門" & "CodeForces題目頁面傳送門" 給定一棵樹$T=(V,E),|V|=2^n 2,|E|=2^n 3$,輸出所有的$x$,使得存在一棵滿二叉樹$T'$,將$T'$中節點$x$的一個兒子刪除並把這個兒子的所有兒子接到$x$下後等於$T$。升序輸出。 $n\le17$。 ...


洛谷題目頁面傳送門 & CodeForces題目頁面傳送門

給定一棵樹\(T=(V,E),|V|=2^n-2,|E|=2^n-3\),輸出所有的\(x\),使得存在一棵滿二叉樹\(T'\),將\(T'\)中節點\(x\)的一個兒子刪除並把這個兒子的所有兒子接到\(x\)下後等於\(T\)。升序輸出。

\(n\le17\)

題目沒有說以哪個點為根,也就是每個點都有可能是根,很自然地想到可以二次掃描與換根。先考慮選一個點作為根,那顯然滿足條件的改補的節點的父結點最多有\(1\)個。這個父結點可以DP出來。

我們將一個子樹分類討論:

  1. 是一棵滿二叉樹。設它的深度為\(d\),則記這顆子樹的特征為有序對\((0,d)\)。這種情況發生當且僅當它有\(2\)棵子樹並且都是矮\(1\)層的滿二叉樹。特殊地,如果它的大小為\(1\),則它的特征為\((0,1)\)
  2. 還原一個節點之後為滿二叉樹。設還原之後的深度為\(d\),補的節點的父結點為\(x\),則記這棵子樹的特征為有序對\((x,d)\)。這種情況發生當且僅當以下任意一個條件為真:

    1. 它的根為\(x\),有\(1\)棵子樹並且這棵子樹大小為\(1\),此時應將改補的節點直接補在\(x\)下。
    2. 它的根為\(x\),有\(3\)棵子樹並且其中\(1\)棵為矮\(1\)層的滿二叉樹,另\(2\)棵為矮\(2\)層的滿二叉樹,此時應將改補的節點補在\(x\)下並將\(2\)棵矮\(2\)層的字樹接在改補的節點下。
    3. 它有\(2\)棵子樹並且一棵為矮\(1\)層的滿二叉樹,另一顆補一個父結點為\(x\)的節點之後為矮\(1\)層的滿二叉樹。
  3. 不管補不補節點都不能成為滿二叉樹。記它的特征為有序對\((-1,-1)\)。顯然,不滿足\(1,2\)則為此種情況。

\(dp_i\)為以\(1\)為根時以\(i\)為根的子樹的特征,則狀態轉移方程是(太♂難寫已隱藏)。這樣一遍\(\mathrm O(2^n)\)DFS則可求出所有節點的DP值。而我們希望找到所有節點為根時的根節點DP值,這個可以二次掃描與換根,即再一遍DFS。每到達一個節點\(x\)時,目前所有節點的DP值均是以\(x\)為整棵樹的根的,所以若\(dp_x=(y,n)(y>0)\),就將\(y\)加入答案序列。那麼此時若要將它的某個兒子\(s\)改為根,那麼改變的只有\(dp_x\)\(dp_s\)。我們可以改一下它們的兒子集合(涉及添加和刪除,用set較為方便),重新算DP值,然後再DFS到\(s\),此時整棵樹的根為\(s\)了。從\(s\)回溯時,再還原\(x\)\(s\)的兒子集合和DP值,去找別的兒子即可。由於換根操作只需要改變\(2\)個節點的信息,所以複雜度是有保證的,一共\(\mathrm O(2^n\log_22^n)=\mathrm O(2^nn)\)\(\log\)set)。

下麵貼代碼:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define X first
#define Y second
const int N=17;
int n;
vector<int> nei[1<<N];/*鄰接表*/ 
set<int> son[1<<N];/*兒子集合*/
void dfs(int x=1,int fa=0){//求出所有節點的兒子集合 
    for(int i=0;i<nei[x].size();i++){
        int y=nei[x][i];
        if(y==fa)continue;
        son[x].insert(y);
        dfs(y,x);
    }
}
pair<int,int> f[1<<N];//DP值,即以[1]為根的子樹的特征 
void calc_f(int x){//通過兒子集合計算DP值,即那個難寫的狀態轉移方程 
    if(son[x].size()==0)f[x]=mp(0,1);
    else if(son[x].size()==1)f[x]=f[*son[x].begin()]==mp(0,1)?mp(x,2):mp(-1,-1);
    else if(son[x].size()==2){
        pair<int,int> x1=f[*son[x].begin()],x2=f[*++son[x].begin()];
        if(x1>x2)swap(x1,x2);
        if(!x1.X&&!x2.X)f[x]=x1.Y==x2.Y?mp(0,x1.Y+1):mp(-1,-1);
        else if(!x1.X&&x2.X>0)f[x]=x1.Y==x2.Y?mp(x2.X,x1.Y+1):mp(-1,-1);
        else f[x]=mp(-1,-1);
    }
    else if(son[x].size()==3){
        pair<int,int> x1=f[*son[x].begin()],x2=f[*++son[x].begin()],x3=f[*++ ++son[x].begin()];
        if(x1>x2)swap(x1,x2);if(x2>x3)swap(x2,x3);if(x1>x2)swap(x1,x2);
        if(!x1.X&&!x2.X&&!x3.X)f[x]=x1.Y==x2.Y&&x2.Y+1==x3.Y?mp(x,x3.Y+1):mp(-1,-1);
        else f[x]=mp(-1,-1);
    }
    else f[x]=mp(-1,-1);
//  printf("f[%d]=(%d,%d)\n",x,f[x].X,f[x].Y);
}
void dp(int x=1,int fa=0){//一遍DFS求出以1為整棵樹的根時的DP數組 
    for(int i=0;i<nei[x].size();i++){
        int y=nei[x][i];
        if(y==fa)continue;
        dp(y,x);
    }
    calc_f(x);
}
vector<int> ans;//答案序列 
void dfs0(int x=1,int fa=0){//二次掃描 
    if(f[x].X>0)ans.pb(f[x].X);//加入答案序列 
    for(int i=0;i<nei[x].size();i++){
        int y=nei[x][i];
        if(y==fa)continue;
        son[x].erase(y);son[y].insert(x);calc_f(x);calc_f(y);//改變兒子集合,重新算DP值 
        dfs0(y,x);
        son[x].insert(y);son[y].erase(x);calc_f(y);calc_f(x);//還原 
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=(1<<n)-3;i++){
        int x,y;
        cin>>x>>y;
        nei[x].pb(y);nei[y].pb(x);
    }
    dfs(); 
    dp();
    dfs0();
    cout<<ans.size()<<"\n";
    sort(ans.begin(),ans.end());
    for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";
    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 幹了這麼多年的前端,之前面試的時候經常會遇到面試官提問:你是如何理解HTML的語義化的? 說實話,之前遇到這個問題的時候,都是從網上找參考答案,然後記下來,用自己的語言重新組織一下,就變成自己的理解了。 為什麼說要重學HTML5的語義化,是因為今年以來,公司安排了一項任務給我,讓我做一個自項目的官網 ...
  • 原文:Interview with a Pornhub Web Developer 譯者:neal1991 welcome to star my articles-translator, providing you advanced articles translation. Any suggest ...
  • 字元串方法幫助您處理字元串。 字元串方法和屬性 原始值,比如“Bill Gates”,無法擁有屬性和方法(因為它們不是對象)。 但是通過 JavaScript,方法和屬性也可用於原始值,因為在執行方法和屬性時 JavaScript 將原始值視為對象。 字元串方法和屬性 原始值,比如“Bill Gat ...
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv ...
  • SSM的練習 : 1開發環境 資料庫:mysql5.5以上版本。 Jdk:1.7 開發環境:Eclipse mars2 Spring:4.2.4 Mybatis:3.2.7 Tomcat:7 2資料庫 資料庫使用mysql 資料庫。 1、創建crm資料庫 2、將參考資料中的sql腳本導入到資料庫中 ... ...
  • 2.SpringMVC介紹 2.1.SpringMVC是什麼 SpringMVC是Spring組織下的一個表現層框架。和Struts2一樣。它是Spring框架組織下的一部分。我們可以從Spring的整體結構中看得出來: 2.2.SpringMVC的作用 1.接收Web請求中的參數 2.把處理好的數... ...
  • 場景 SpringCloud學習之運行第一個Eureka程式: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/90611451 SpringCloud -創建統一的依賴管理: https://blog.csdn.net/BADAO ...
  • 場景 Spring Cloud 為開發者提供了在分散式系統(配置管理,服務發現,熔斷,路由,微代理,控制匯流排,一次性 Token,全居瑣,Leader 選舉,分散式 Session,集群狀態)中快速構建的工具,使用 Spring Cloud 的開發者可以快速的啟動服務或構建應用、同時能夠快速和雲平臺 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...