排序(並查集&&雜湊函式)
【問題描述】
給出一個包含正整數的陣列P(p1,…,pn),並假設陣列P經過排序後變成陣列Q(q1,…,qn)。定義合法替換集合,如果整數對(X,Y)屬於合法交換集合,則表示你可以交換陣列p中位置X和位置Y的元素。現在有Q個操作(詢問),詢問分為以下四種型別:
1.交換位置A和位置B的元素
2.將整數對(A,B)加入到合法交換集合
3.詢問是否能通過合法交換集合中的操作,將陣列P進行排序。(注意:過程中可以以任何順序執行交換操作,並且每個交換操作可以執行任意多次)
4.定義位置對(A,B)是相連的當且僅當位置A的元素可以僅通過合法交換集合中的操作移動到位置B。
定義所有和位置A相連的位置組成的集合為A的群集。如果對於每一個在A的群集中的位置j,都能通過一系列合法交換集合中的操作使得pj=qj,則稱A的群集是良好的。 你需要回答,有多少對不同的位置對(A,B)滿足:
a)位置A和位置B是不相連的
b)A的群集和B的群集都不是良好的
c)如果我們將位置對(A,B)加入到合法交換集合中,A的群集將變成良好的。
注意:在計算時,位置對(A,B)和位置對(B,A)被視為不同的位置對。
【輸入格式】
第一行兩個正整數,N和Q(1<=N, Q<=1,000,000)
第二行包含N個正整數p1,…,pn(1<=p1,…,pn<=1,000,000)
接下來Q行,每行表示一個操作:
每行第一個數字表示操作的種類,(1,2,3或4)
如果操作種類是1或2,後面緊接著兩個正整數A,B(1<=A,B<=N)表示位置對(A,B)
【輸出格式】
對於每一個詢問(種類為3、4的操作),輸出一行作為詢問的答案。
對於種類為3的詢問的答案輸出“YES”或“NO”(不包含雙引號)。“YES”表示能通過合法交換集合的操作將陣列P排序,“NO”則表示不能。
對於種類為4的詢問輸出,輸出一個非負整數表示對應的答案。
【輸入樣例】
【樣例1】
3 5
1 3 2
4
3
2 2 3
4
3
【樣例2】
5 5
4 2 1 4 4
3
4
1 1 3
3
4
【樣例3】
4 10
2 1 4 3
3
4
1 1 2
3
4
2 2 3
2 1 2
4
2 3 4
3
【輸出樣例】
【樣例1】
1
NO
0
YES
【樣例2】
NO
1
YES
0
【樣例3】
NO
2
NO
1
3
YES
【樣例解釋】
【樣例解釋1】
第一個詢問答案是1,因為只有位置對(2,3)符合所有的條件,第二個詢問答案是NO,因為交換集合為空,數字2和3沒有辦法交換到正確位置,在第三次操作後,我們把位置對(2,3)加入到交換集合中,第四次操作(詢問)答案為0因為2和3已經相連,第五次操作(詢問)答案是YES,因為可以通過位置對(2,3)把陣列排好序。
【資料範圍】
50%的資料滿足N,Q<=1000。
【來源】
這道題一看就知道是並查集,但具體怎麼做就難了。
要定義一個雜湊函式,來不重複的代表每個數的權值。
然後定義2個陣列。
q(i)表示P中i這個並查集所代表的位置的元素的權值和。
p(i)表示Q中i這個並查集所代表的位置的元素的權值和。
然後用map存每個p(i)-q(i)的值。
當我們要找互相配合起來和諧的並查集時就直接找2個差值加起來為0的就可以了,在中間邊變化邊記錄就好。
而要全部和諧就得所有差值都為0,直接看map中為0的個數是不是n個就可以了。
其他就是並查集了。
具體程式碼如下:
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=1000005;
const ll mod=2000005ll;
ll q[maxn],p[maxn],a[maxn];
map<ll,int>mp;
int n,m,b[maxn],pa[maxn],c[maxn];
int num=0,size[maxn];
int find(int x){return pa[x]==x?x:pa[x]=find(pa[x]);}
void un(int x,int y)
{
int px=find(x),py=find(y);
if(px==py) return;
mp[p[px]-q[px]]-=size[px];
if(q[px]-p[px]!=0) num-=size[px]*mp[q[px]-p[px]];
mp[p[py]-q[py]]-=size[py];
if(q[py]-p[py]!=0)num-=size[py]*mp[q[py]-p[py]];
q[px]+=q[py];
p[px]+=p[py];
size[px]+=size[py];
if(q[px]-p[px]!=0) num+=size[px]*mp[q[px]-p[px]];
mp[p[px]-q[px]]+=size[px];
pa[py]=px;
}
int read()
{
int x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
n=read();m=read();
a[1]=17;
for(int i=2;i<=1000000;i++)
{
a[i]=(a[i-1]*17)%mod;
}
int x,id,y,px,py;
for(int i=1;i<=n;i++)
{
c[i]=b[i]=read();
q[i]=a[b[i]];
pa[i]=i;
size[i]=1;
}
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
p[i]=a[b[i]];
if(q[i]-p[i]!=0)num+=mp[q[i]-p[i]];
mp[p[i]-q[i]]++;
}
while(m--)
{
id=read();
if(id==1)
{
x=read();y=read();
px=find(x),py=find(y);
if(px==py)
{
swap(c[x],c[y]);
continue;
}
mp[p[px]-q[px]]-=size[px];
if(q[px]-p[px]!=0) num-=size[px]*mp[q[px]-p[px]];
mp[p[py]-q[py]]-=size[py];
if(q[py]-p[py]!=0)num-=size[py]*mp[q[py]-p[py]];
q[px]+=a[c[y]]-a[c[x]];
q[py]+=a[c[x]]-a[c[y]];
mp[p[px]-q[px]]+=size[px];
if(q[px]-p[px]!=0)num+=size[px]*mp[q[px]-p[px]];
mp[p[py]-q[py]]+=size[py];
if(q[py]-p[py]!=0)num+=size[py]*mp[q[py]-p[py]];
swap(c[x],c[y]);
}
if(id==2)
{
x=read();y=read();
un(x,y);
}
if(id==3)
{
if(mp[0]==n) printf("YES\n");
else printf("NO\n");
}
if(id==4)
{
printf("%d\n",num);
}
}
return 0;
}
相關文章
- 雜湊函式函式
- 查詢(3)--雜湊表(雜湊查詢)
- Fortran雜湊函式庫的使用函式
- 14-2 雜湊函式設計函式
- Day76.雜湊表、雜湊函式的構造 -資料結構函式資料結構
- 一些“並查集”雜燴並查集
- 雜湊函式與資料完整性 (^=◕ᴥ◕=^)函式
- PostgreSQL-並行雜湊JOIN分析查詢效能爆炸SQL並行
- 雜湊函式(Hash Functions - 雜湊函式)的基本介紹(SHA-2,SHA-256,MD-5,Scrypt,BCrypt等)函式Function
- 【資料結構】查詢結構(二叉排序樹、ALV樹、雜湊技術雜湊表)資料結構排序
- 字串查詢(字串雜湊)字串
- 基於雜湊函式的簽名,Part-1函式
- 如何判斷一個雜湊函式的好壞函式
- 雜湊技術【雜湊表】查詢演算法 PHP 版演算法PHP
- Solr複雜查詢一:函式查詢Solr函式
- hdu 1811 並查集+拓撲排序並查集排序
- 雜湊查詢演算法演算法
- 雜湊查詢 兩數之和
- 10g新增排序雜湊聚集表排序
- iOS資料加密(Base64,雜湊函式,AES,RSA)iOS加密函式
- 並查集到帶權並查集並查集
- js 雜湊雜湊值的模組JS
- 雜湊表(雜湊表)詳解
- 【並查集】【帶偏移的並查集】食物鏈並查集
- 雜湊
- 查詢演算法及雜湊表演算法
- 雜湊表(雜湊表)原理詳解
- 【尋跡#3】 雜湊與雜湊表
- 並查集(一)並查集的幾種實現並查集
- 第二章 :查詢與排序-------2.10常見函式的複雜度計算排序函式複雜度
- 3.1並查集並查集
- 並查集(小白)並查集
- 使用pwdump 匯出本地windows SAM雜湊並破解Windows
- 347前 K 個高頻元素(雜湊表、堆排序)排序
- 【PHP資料結構】雜湊表查詢PHP資料結構
- 樹雜湊
- 雜湊碰撞
- 字串雜湊字串