洛谷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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...