P2391 白雪皑皑

原题链接

考察:并查集

并查集维护序列的连通性

Y总在课上提过的题目,本蒟蒻果然不会

思路:

       本质是快速染色某个区间.并查集可以帮助我们快速找到第一个未染色的点.

       设p[i]为以i为起点第一个需要还未涂色的点(包括i) .通过findf(i)可以帮助我们找到第一个未染色的点.我们在for循环染色[l,r]区间时,i可以直接跳到findf(i)处.这样压缩了染色路径.

       一个阅读理解的问题是染色l ~ r之间的点.如果l>r 是swap而不是continue

 1 #include <iostream> 
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 1000010;
 6 int n,m,ps,q,p[N],color[N]; 
 7 int get(int i,int l,int r)
 8 {
 9     return (i*l+r)%n+1;
10 }
11 int findf(int x) 
12 {
13     if(p[x]!=x) p[x] = findf(p[x]);
14     return p[x];
15 }
16 int main()
17 {
18     scanf("%d%d%d%d",&n,&m,&ps,&q);
19     for(int i=1;i<=n+5;i++) p[i] = i;
20     for(int i=m;i>=1;i--)
21     {
22         int l = get(i,ps,q),r = get(i,q,ps);
23         if(l>r) swap(l,r);
24         l = findf(l);
25         while(l<=r)
26         {
27             color[l] = i;
28             p[l] = findf(l+1);
29             l = findf(l+1);
30         }
31     }
32     for(int i=1;i<=n;i++)
33         printf("%d\n",color[i]);
34     return 0;
35 }

 

posted @ 2021-05-13 21:45  acmloser  阅读(48)  评论(0编辑  收藏  举报