程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> PKU2985(The k-th Largest Group)線段樹+並查集

PKU2985(The k-th Largest Group)線段樹+並查集

編輯:C++入門知識

[cpp]   /********************************************  題目大意:  n只貓,m個操作;  0 a b  合並兩個貓所在的集合;  1 k    詢問在當前的所有的集合中含有的貓的個數第k大的為多大;    算法思想:  合並操作應該用並查集;  查詢操作可以用線段樹;  開始將所有的數據輸入進來,利用並查集計算出所有種集合的大小;  然後根據集合的大小建樹查詢就可以了;  *********************************************/   #include<iostream>   #include<cstring>   #include<cstdlib>   #include<cstdio>   #include<climits>   #include<algorithm>   using namespace std;      #define L l,m,u<<1   #define R m+1,r,u<<1|1      const int N=200010;      struct darling   {       int op;//操作判斷       int x,y;   } d[N];//輸入數據      struct cat   {       int pre;//前驅結點       int rank;//並查集的高度,即貓的數量   } a[N];      struct Node   {       int l,r,s;   } t[N*4];//線段樹      int vs1[N],vs2[N];//記錄每個集合裡面貓的數量,即rank   int flag[N];//記錄每個結點的位置,方便線段樹插入   int cnt1,cnt2;//記錄集合的數量   int n,m;      void Build(int l,int r,int u)//建樹   {       t[u].l=l;       t[u].r=r;       t[u].s=0;       if(l==r)           return;       int m=(l+r)>>1;       Build(L);       Build(R);   }      void Insert(int x,int n,int u)//插入結點   {       if(t[u].l==t[u].r)       {           t[u].s+=n;           return;       }       int m=(t[u].l+t[u].r)>>1;       if(x<=m)           Insert(x,n,u<<1);       else           Insert(x,n,u<<1|1);       t[u].s=t[u<<1].s+t[u<<1|1].s;   }      int Query(int k,int u)//查詢   {       if(t[u].l==t[u].r)       {           return t[u].l;       }       if(k>t[u<<1|1].s)           return Query(k-t[u<<1|1].s,u<<1);       return Query(k,u<<1|1);   }      void Init(int x)//初始化並查集   {       for(int i=0; i<=x; i++)       {           a[i].pre=i;           a[i].rank=1;       }   }      int Find(int x)//查詢前驅結點   {       if(a[x].pre!=x)           return a[x].pre=Find(a[x].pre);       return a[x].pre;   }      void Union(int x,int y)//合並操作   {       x=Find(x);       y=Find(y);       if(x==y)           return;       if(a[x].rank>a[y].rank)       {           a[x].rank+=a[y].rank;           vs1[++cnt1]=a[x].rank;           a[y].pre=x;       }       else       {           a[y].rank+=a[x].rank;           vs1[++cnt1]=a[y].rank;           a[x].pre=y;       }   }      void solve()   {       for(int i=0; i<m; i++)       {           if(d[i].op)           {               int v=Query(d[i].x,1);               printf("%d\n",vs2[v]);           }           else           {               int x1=Find(d[i].x);               int y1=Find(d[i].y);               if(x1==y1)                   continue;               int x2=a[x1].rank;               int y2=a[y1].rank;               if(x2==y2)               {                   Insert(flag[x2],-2,1);               }               else               {                   Insert(flag[x2],-1,1);                   Insert(flag[y2],-1,1);               }               Insert(flag[x2+y2],1,1);               Union(x1,y1);           }       }   }      int main()   {       //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);       while(~scanf("%d%d",&n,&m))       {           Init(n);           vs1[1]=1;           cnt1=1;           for(int i=0; i<m; i++)           {               scanf("%d",&d[i].op);               if(d[i].op)               {                   scanf("%d",&d[i].x);               }               else               {                   scanf("%d%d",&d[i].x,&d[i].y);                   Union(d[i].x,d[i].y);               }           }           int cnt2=1;           sort(vs1+1,vs1+cnt1+1);           for(int i=2; i<=cnt1; i++)//記錄多少組不同           {               if(vs1[i]!=vs1[cnt2])                   vs1[++cnt2]=vs1[i];           }           for(int i=1; i<=cnt2; i++)           {               flag[vs1[i]]=i;               vs2[i]=vs1[i];           }           Build(1,cnt2,1);           Insert(1,n,1);           Init(n);           cnt1=0;           solve();       }       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved