洛谷P3224 [HNOI2012]永無鄉

来源:http://www.cnblogs.com/zwfymqz/archive/2017/12/05/7988406.html
-Advertisement-
Play Games

題目描述 永無鄉包含 n 座島,編號從 1 到 n,每座島都有自己的獨一無二的重要度,按照重要度可 以將這 n 座島排名,名次用 1 到 n 來表示。某些島之間由巨大的橋連接,通過橋可以從一個島 到達另一個島。如果從島 a 出發經過若幹座(含 0 座)橋可以到達島 b,則稱島 a 和島 b 是連 通 ...


題目描述

永無鄉包含 n 座島,編號從 1 到 n,每座島都有自己的獨一無二的重要度,按照重要度可 以將這 n 座島排名,名次用 1 到 n 來表示。某些島之間由巨大的橋連接,通過橋可以從一個島 到達另一個島。如果從島 a 出發經過若幹座(含 0 座)橋可以到達島 b,則稱島 a 和島 b 是連 通的。

現在有兩種操作:

B x y 表示在島 x 與島 y 之間修建一座新橋。

Q x k 表示詢問當前與島 x連通的所有島中第 k 重要的是哪座島,即所有與島 x 連通的島中重要度排名第 k 小的島是哪 座,請你輸出那個島的編號。

輸入輸出格式

輸入格式:

 

輸入文件第一行是用空格隔開的兩個正整數 n 和 m,分別 表示島的個數以及一開始存在的橋數。接下來的一行是用空格隔開的 n 個數,依次描述從島 1 到島 n 的重要度排名。隨後的 m 行每行是用空格隔開的兩個正整數 ai 和 bi,表示一開始就存 在一座連接島 ai 和島 bi 的橋。後面剩下的部分描述操作,該部分的第一行是一個正整數 q, 表示一共有 q 個操作,接下來的 q 行依次描述每個操作,操作的格式如上所述,以大寫字母 Q 或B 開始,後面跟兩個不超過 n 的正整數,字母與數字以及兩個數字之間用空格隔開。 對於 20%的數據 n<=1000,q<=1000 對於 100%的數據 n<=100000,m<=n,q<=300000

 

輸出格式:

 

對於每個 Q x k 操作都要依次輸出一行,其中包含一個整數,表 示所詢問島嶼的編號。如果該島嶼不存在,則輸出-1。

 

輸入輸出樣例

輸入樣例#1: 複製
5  1
4  3 2 5 1
1  2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3



對於聯通性問題,我們可以用並查集維護
對於動態集合第k大,我們可以用平衡樹維護
這樣的話維護n個splay
然後每次暴力合併就好
註意要用啟髮式合併
只有這樣插入點的複雜度才是嚴格$O(logn)$


  1 #include<iostream>
  2 #include<cstdio>
  3 using namespace std;
  4 const int MAXN=1e6+10;
  5 const int maxn=0x7fffff;
  6 #define ls tree[k].ch[0]
  7 #define rs tree[k].ch[1]
  8 inline int read()
  9 {
 10     char c=getchar();int x=0,f=1;
 11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 12     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
 13     return x*f;
 14 }
 15 struct node
 16 {
 17     int v,fa,ch[2],sum;
 18 }tree[MAXN];
 19 int pointnum,tot;
 20 int root[MAXN],val[MAXN],f[MAXN],n,m;
 21 char opt[10];
 22 int iden(int x){return tree[tree[x].fa].ch[0]==x?0:1;}
 23 inline void connect(int x,int fa,int how){tree[x].fa=fa;tree[fa].ch[how]=x;}
 24 inline void update(int x)
 25 {tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+1;}
 26 inline void rotate(int x)
 27 {
 28     int y=tree[x].fa;
 29     int R=tree[y].fa;
 30     int Rson=iden(y);
 31     int yson=iden(x);
 32     int b=tree[x].ch[yson^1];
 33     connect(b,y,yson);
 34     connect(y,x,yson^1);
 35     connect(x,R,Rson);
 36     update(y);update(x);
 37 }
 38 void splay(int x,int to)// 把編號為pos的節點旋轉到編號為to的節點 
 39 {
 40     while(tree[x].fa!=to)
 41     {
 42         int y=tree[x].fa,z=tree[y].fa;
 43         if(z!=to)
 44             (tree[z].ch[0]==y)^(tree[y].ch[0]==x)?rotate(x):rotate(y);
 45         rotate(x);
 46     }
 47     if(to<=n)    root[to]=x;
 48 }
 49 void insert(int v,int pos)
 50 {
 51     int now=root[pos],fa=pos;
 52     while(now&&tree[now].v!=v)
 53         fa=now,now=tree[now].ch[v>tree[now].v];
 54     now=++tot;
 55     tree[now].sum=1;
 56     tree[now].fa=fa;
 57     if(fa>n)    tree[fa].ch[v>tree[fa].v]=now;
 58     tree[now].v=v;tree[now].ch[0]=tree[now].ch[1]=0;
 59     splay(now,pos);
 60 }
 61 int rank(int pos,int k)
 62 {
 63     int now=root[pos];
 64     if(tree[now].sum<k)    return -1;
 65     while(1)
 66     {
 67         if(tree[tree[now].ch[0]].sum+1<k)    k-=tree[tree[now].ch[0]].sum+1,now=tree[now].ch[1];
 68         else    if(tree[tree[now].ch[0]].sum>=k)    now=tree[now].ch[0];
 69         else    return tree[now].v;
 70     }
 71     splay(now,root[pos]);
 72     return tree[now].v;
 73 }
 74 int Gets(int x)
 75 {
 76     if(f[x]==x)    return f[x];
 77     else return f[x]=Gets(f[x]);
 78 }
 79 void DFS(int k,int fa)
 80 {
 81     if(ls)    DFS(ls,fa);
 82     if(rs)    DFS(rs,fa);
 83     insert(tree[k].v,fa);
 84 }
 85 void Merge(int x,int y)
 86 {
 87     x=Gets(x),y=Gets(y);
 88     if(x==y)    return ;
 89     if(tree[root[x]].sum>tree[root[y]].sum)    swap(x,y);
 90     f[x]=y;
 91     DFS(root[x],y);
 92 }
 93 int main()
 94 {
 95     #ifdef WIN32
 96     freopen("a.in","r",stdin);
 97     #else
 98     #endif
 99     n=read(),m=read();
100     tot=n*2;
101     for(int i=1;i<=n;i++)
102     {
103         int p=read();
104         val[p]=i;
105         tree[i+n].v=p;
106         tree[i+n].sum=1;
107         tree[i+n].fa=i;
108         root[i]=i+n;        
109         f[i]=i;
110     }
111     for(int i=1;i<=m;i++)
112     {
113         int x=read(),y=read();
114         Merge(x,y);
115     }
116     int q=read();
117     while(q--)
118     {
119         int x,y;
120         scanf("%s",opt);
121         x=read();y=read();
122         if(opt[0]=='B')    
123             Merge(x,y);
124         else 
125         {
126             int ans=rank(Gets(x),y);
127             printf("%d\n",ans==-1?ans:val[ans]);
128         }
129     }
130 } 

 





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

-Advertisement-
Play Games
更多相關文章
  • 1、到官網http://www.oracle.com/technetwork/java/javase/downloads/index.html下載JDK 2、安裝 打開dmg包 3、測試 在終端上輸入: java version 安裝完成。 ...
  • 前言 java8里最大亮點是lambda,讓我們用習慣C# linq的語法,也能眼前一亮。但是比起C#的語法糖還是差的很遠。 差集、並集、交集 ...
  • 定義: 將一個類的介面轉換成客戶希望的另外一個介面。適配器模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。 角色: 目標(Target)角色:這就是所期待得到的介面,也就是這類的介面是符合我們要求的。 源(Adapee)角色:我們要使用的介面,但是這個介面不符合我們的要求,也就是現在需 ...
  • 參考Spring Cloud官方文檔第13、14、15章 13. Circuit Breaker: Hystrix Clients Netflix提供了一個叫Hystrix的類庫,它實現了斷路器模式。在微服務架構中,通常一個微服務會調用多個其他的微服務。一個相對低層級的服務失敗可能造成上層應用的級聯 ...
  • 2017年11月底開始python的學習。選擇python 3.6。 賬號登陸的粗糙實現。 ...
  • 功能 1.天氣預報 2.區域網對戰 展示 java學習群669823128 部分源碼 package game.weather; import java.util.HashMap; public class Weather { /** * @Fields 今天的天氣數據,整體 */ private ...
  • 在大多數大公司,像應用伺服器軟體的安裝、部署都是運維的事情,其實自己去嘗試部署一下,也是有收穫的。 周末在家無聊,正好嘗試了Linux下的rabbitMq安裝過程,做了記錄,希望有用到的人可以做下參考。 安裝環境: Linux: centOS 7.0 mini版 rabbitMq: 3.6.2 查詢 ...
  • 上一篇《Git命令彙總基礎篇》總結了使用Git的基本命令,這一篇作為補充主要給大家講一些平時使用中的技巧和總結 。 學會了這些命令,已經基本解決了使用Git中大部分問題。 1.gitignore 全局配置忽略文件 git config --global core.excludesfile ~/.gi ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...