您的位置:首页 > 其它

[并查集]染色问题

2013-10-17 08:30 330 查看
题目大意:

平面上有n个珠子排成一排, 每个珠子初始颜色为0,你要对他们进行m次染色,

每次你选定l和r,然后把[l,r]之间的珠子染成编号c的颜色,

每个珠子的最终颜色为它曾经染过的编号最大的颜色,统计每个珠子最终的颜色。

由于数据较大,为了减少输出所用的不必要的时间,请采取以下方法输出:

假如a[i]为第i个珠子的最终颜色

for i := 1 to n do ans := (ans * 1200007 + a[i]) mod 999911659;

solution:

把color从大到小排序,F[i]数组代表i左边第一个未被染色的点。

每次从要染色的段的右端不断往左寻找F[i]进行染色

F[R]->F[F[R]-1]-> F[F[F[R]-1]-1] ..-> L

从而避免了多次访问相同节点 。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[1000010];
int f[1000010];
long long res;

struct Edge
{
int u;
int v;
int c;
friend bool operator <
(const Edge a,const Edge b)
{
return a.c>b.c;
}
}G[2000010];

int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
}

int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;++i)
scanf("%d %d %d",&G[i].u,&G[i].v,&G[i].c);
sort(G+1,G+1+m);
for(int i=1;i<=n;++i)f[i]=i;
for(int i=1;i<=m;++i)
{
int t=find(G[i].v);
while(t>=G[i].u)
{
a[t]=G[i].c;
f[t]=find(f[t-1]);
t=f[t];
}
}
for(int i=1;i<=n;++i)
res=(res*1200007+a[i])%999911659;
printf("%lld\n",res);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: