码迷,mamicode.com
首页 > 其他好文 > 详细

【bzoj1483】[HNOI2009]梦幻布丁 set

时间:2017-12-29 12:16:58      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:font   表示   print   数字   style   tor   oid   void   char   

【bzoj1483】[HNOI2009]梦幻布丁

Description

N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色.

Input

第一行给出N,M表示布丁的个数和好友的操作次数. 第二行N个数A1,A2…An表示第i个布丁的颜色从第三行起有M行,对于每个操作,若第一个数字是1表示要对颜色进行改变,其后的两个整数X,Y表示将所有颜色为X的变为Y,X可能等于Y. 若第一个数字为2表示要进行询问当前有多少段颜色,这时你应该输出一个整数. 0

Output

针对第二类操作即询问,依次输出当前有多少段颜色.

Sample Input

4 3
1 2 2 1
2
1 2 1
2

Sample Output

3
1
 
题解:
  c++stl
  
1:将两个队列合并,有若干队列,总长度为n,直接合并,最坏O(N),
 
2:启发式合并呢?
 
每次我们把短的合并到长的上面去,O(短的长度)
 
咋看之下没有多大区别,
 
下面让我们看看均摊的情况:
 
1:每次O(N)
2:每次合并后,队列长度一定大于等于原来短的长度的两倍。
 
这样相当于每次合并都会让短的长度扩大一倍以上,
 
最多扩大logN次,所以总复杂度O(NlogN),每次O(logN)。
 1 #include<cstring>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cstdio>
 6 #include<set>
 7 
 8 #define N 1000007
 9 #define ll long long
10 using namespace std;
11 inline int read()
12 {
13     int x=0,f=1;char ch=getchar();
14     while(ch>9||ch<0){if (ch==-) f=-1;ch=getchar();}
15     while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
16     return x*f;
17 }
18 
19 int n,m,ans;
20 int fa[N],v[N];
21 set<int>t[N];
22 
23 void solve(int a,int b)
24 {
25     for(set<int>::iterator i=t[a].begin();i!=t[a].end();i++)
26     {
27         if(v[*i-1]==b)ans--;
28         if(v[*i+1]==b)ans--;
29         t[b].insert(*i);
30     }
31     for(set<int>::iterator i=t[a].begin();i!=t[a].end();i++)v[*i]=b;
32     t[a].clear();
33 }
34 int main()
35 {
36     n=read();m=read();
37     for(int i=1;i<=n;i++)v[i]=read();
38     for(int i=1;i<=n;i++)
39     {
40         fa[v[i]]=v[i];
41         if(v[i]!=v[i-1])ans++;
42         t[v[i]].insert(i);
43     }
44     for(int i=1;i<=m;i++)
45     {
46         int f=read(),a,b;
47         if(f==2)printf("%d\n",ans);
48         else 
49         {
50             a=read();b=read();
51             if(a==b)continue;
52             if(t[fa[a]].size()>t[fa[b]].size())
53                 swap(fa[a],fa[b]);
54             a=fa[a];b=fa[b];
55             solve(a,b);
56         }
57     }
58 }

 

【bzoj1483】[HNOI2009]梦幻布丁 set

标签:font   表示   print   数字   style   tor   oid   void   char   

原文地址:https://www.cnblogs.com/fengzhiyuan/p/8143107.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!