小Z的梦 并查集

问题描述

小Z做了一个梦,梦中他终于得到了梦寐以求的德国牧羊犬,而且有好多只,小Z数了一下一共有N只,但不幸的是所有牧羊犬竟然都是白色的,小Z最不喜欢白色。于是他让所有牧羊犬排成一排,准备对它们进行M次染色操作。每次他将连续的多个牧羊犬染成特定的某种颜色。一个牧羊犬最终的颜色是最后一次被染的颜色。如果某个牧羊犬没有被染过色,那么它的颜色就是白色。

小Z决定采用下面的方法染色:在第i次染色操作中,把包括第i×A+BModN+1i×B+AModN+1

之间的所有牧羊犬染成颜色i,其中A,B是特定的两个正整数。他想立刻知道最后每个牧羊犬的颜色。

输入格式

第一行四个正整数N,M,A,B

输出格式

一共输出N行,第i行表示第i个牧羊犬的最终颜色(如果最终颜色是白色就输出0)。

输入样例

4 3 2 4

输出样例

2
2
3
0

限制与约定

1N10000001M10000000

1M×A+BM×A+B2311

时间限制:5s

空间限制:128MB

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 1000000 + 10 ;
int f[maxn],ans[maxn];
int find(int x)
{
    if( !f[x] || f[x]==x ) return f[x]=x;
    return f[x]=find(f[x]);
}
int main()
{
    int n,m,a,b;
    cin>>n>>m>>a>>b;
//    for(int i=1;i<=n;i++) f[n]=i;
    for(int i=m;i;i--)
    {
        int l=(i*a+b)%n+1;
        int r=(i*b+a)%n+1;
        if(l>r) swap(l,r);
        for(int j=find(l);j<=r;j=find(j))
        {
            ans[j]=i;
            f[j]=j+1;
        }
    }
    for(int i=1;i<=n;i++)
        printf("%d\n",ans[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hfang/p/11240006.html
今日推荐