bzoj 2054: 疯狂的馒头

2054: 疯狂的馒头

Description

Input

第一行四个正整数N,M,p,q

Output

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

Sample Input

4 3 2 4

Sample Output

2
2
3
0

HINT

题解:

m<=10^7,时限有10s,一开始就想到暴力模拟。

但是这题还是有些技巧的,首先对与一个点,影响它颜色的是最后一次修改,所以可以倒着枚举。

这没修改呢??

这边可以巧妙地运用并查集,如果改了一个点,那么下次就不用再改了,就把这个点直接指向下一个点,修改l,r这一段的时候直接跳过。

#include<stdio.h>
#include<iostream>
using namespace std;
const int N=1000005;
int n,m,p,q,k,i,j,x,y,f[N],a[N];
int get(int x)
{
    if(f[x]==x) return x;else return f[x]=get(f[x]);
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&p,&q);
    for(i=1;i<=n+1;i++) f[i]=i;
    k=0;
    for(i=m;i>=1;i--)
    {
        x=(i*p%n+q)%n+1;
        y=(i*q%n+p)%n+1;
        if(x>y) swap(x,y);
        for(j=get(x);j<=y;j=get(j))
        {
            a[j]=i,f[j]=j+1,k++;
            if(k==n) break;
        }
    }
    for(i=1;i<=n;i++)
        printf("%d\n",a[i]);
    return 0;
}

 

posted @ 2016-06-05 18:48  lwq12138  阅读(1511)  评论(1编辑  收藏  举报