记录编号 |
294222 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HZOI 2016]seq |
最终得分 |
100 |
用户昵称 |
AntiLeaf |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
2.852 s |
提交时间 |
2016-08-11 19:34:28 |
内存使用 |
6.34 MiB |
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
namespace mine{
inline int getint(){
static int __c,__x;
static bool __neg;
__x=0;
__neg=false;
do __c=getchar();while(__c==' '||__c=='\n'||__c=='\r'||__c=='\t');
if(__c=='-'){
__neg=true;
__c=getchar();
}
for(;__c>='0'&&__c<='9';__c=getchar())__x=__x*10+(__c^48);
if(__neg)return -__x;
return __x;
}
inline void putint(int __x){
static int __a[40],__i,__j;
static bool __neg;
__neg=__x<0;
if(__neg)__x=-__x;
__i=0;
do{
__a[__i++]=__x%10+48;
__x/=10;
}while(__x);
if(__neg)putchar('-');
for(__j=__i-1;__j^-1;__j--)putchar(__a[__j]);
}
}
using namespace mine;
const int maxn=1000100;
int findroot(int);
void mergeset(int,int);
int n,m,q,x,y,prt[maxn],a[maxn],first[maxn]={0};
bool exi[maxn]={false};
inline int MAIN(){
freopen("hzoi_seq.in","r",stdin);
freopen("hzoi_seq.out","w",stdout);
n=getint();
m=getint();
q=getint();
for(int i=1;i<=n;i++){
x=getint();
prt[i]=i;
if(!exi[x]){
exi[x]=true;
first[x]=i;
a[i]=x;
}
else mergeset(i,first[x]);
}
while(q--){
x=getint();
y=getint();
if(!exi[x]||x==y)continue;
exi[x]=false;
if(!exi[y]){
exi[y]=true;
a[findroot(first[x])]=y;
first[y]=first[x];
}
else mergeset(first[x],first[y]);
first[x]=0;
}
for(int i=1;i<=n;i++){
putint(a[findroot(i)]);
putchar(' ');
}
fclose(stdin);
fclose(stdout);
return 0;
}
inline int findroot(int x){
int r=prt[x],y;
while(prt[r]!=r)r=prt[r];
for(y=prt[x];y!=r;y=prt[y]){
prt[x]=r;
x=y;
}
return prt[x];
}
inline void mergeset(int x,int y){//把x合并到y中
int rx=findroot(x),ry=findroot(y);
if(rx==ry)return;
prt[rx]=ry;
}
int hzoier=MAIN();
int main(){;}
/*
解法:
使用并查集,其中每个节点表示seq中的下标,
记录附加信息表示这个下标对应的数,
修改时分两种情况:
1.b在序列中
把对应的两个数合并。
2.b不在序列中
直接修改根节点的附加信息即可。
进行完所有修改操作之后对于每个下标直接输出根节点的附加信息即可。
预处理与输出O(n),单次修改操作复杂度O(1),总复杂度O(n+q),很够用了。
*/