这个题调了我2个小时。。。。各种错误。
可以用LCT+离线做,不过因为一直在排序,最后编号搞错了,想了下就调出来了
/**************************************************************
Problem: 2594
User: Clare
Language: C++
Result: Accepted
Time:15476 ms
Memory:85072 kb
****************************************************************/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
using namespace std;
#define N 1100010
#define INF 0x7fffffff
int n,m,Q,Ans[N],tot1,tot2,Del[N],pre[N];
int fa[N],c[N][2],Max[N],v[N];
bool Rev[N],flag[N];
struct Ask{
int id;
int u,v;
}q[N];
struct Edge{
int u,v,w,id;
}A[N],B[N];
stack<int> st;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int Cmp1(const Edge &a,const Edge &b)
{
return a.u==b.u?a.v<b.v:a.u<b.u;
}
int Cmp2(const Edge &a,const Edge &b)
{
return a.id<b.id;
}
int Cmp3(const Edge &a,const Edge &b)
{
return a.w<b.w;
}
int Find(int x)
{
if(pre[x]!=x)pre[x]=Find(pre[x]);
return pre[x];
}
bool Pd_root(int k)
{
return !(c[fa[k]][0]==k)&&!(c[fa[k]][1]==k);
}
void Pushup(int k)
{
int l=c[k][0],r=c[k][1];
Max[k]=k;
if(v[Max[k]]<v[Max[l]])Max[k]=Max[l];
if(v[Max[k]]<v[Max[r]])Max[k]=Max[r];
}
void Pushdown(int k)
{
int l=c[k][0],r=c[k][1];
if(Rev[k])
{
Rev[k]^=1;Rev[r]^=1;Rev[l]^=1;
swap(c[k][0],c[k][1]);
}
}
void Rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if(c[y][0]==x)l=0;else l=1;r=l^1;
if(Pd_root(y));
else if(c[z][0]==y)c[z][0]=x;
else c[z][1]=x;
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
Pushup(y);Pushup(x);
}
void Splay(int x)
{
int i;
for(i=x;!Pd_root(i);i=fa[i])
st.push(i);
st.push(i);
while(!st.empty())
{
int now=st.top();st.pop();
Pushdown(now);
}
while(!Pd_root(x))
{
int y=fa[x],z=fa[y];
if(!Pd_root(y))
{
if(c[y][0]==x^c[z][0]==y)
Rotate(x);
else Rotate(y);
}
Rotate(x);
}
}
void Access(int x)
{
for(int t=0;x;t=x,x=fa[x])
Splay(x),c[x][1]=t,Pushup(x);
}
void Move_to_root(int x)
{
Access(x);Splay(x);Rev[x]^=1;
}
void Join(int x,int y)
{
Move_to_root(x);fa[x]=y;Splay(x);
}
void Cut(int x,int y)
{
Move_to_root(x);Access(y);Splay(y);
if(c[y][0]==x)
fa[x]=c[y][0]=0;
else fa[x]=c[y][1]=0;
Pushup(y);Pushup(x);
}
void Split(int x,int y)
{
Move_to_root(x);Access(y);Splay(y);
}
int Find_root(int x)
{
Access(x);Splay(x);
while(c[x][0])
x=c[x][0];
return x;
}
int main()
{
n=read();m=read();Q=read();
for(int i=1;i<=n;i++)
Max[i]=pre[i]=i;
for(int i=1;i<=m;i++)
{
int t1=read(),t2=read();
A[i].u=min(t1,t2);A[i].v=max(t1,t2);A[i].w=read();A[i].id=i;
}
sort(A+1,A+m+1,Cmp1);
for(int i=1;i<=Q;i++)
{
int kind=read();
int t1=read(),t2=read();
if(kind==1)
{
q[++tot1].u=min(t1,t2);q[tot1].v=max(t1,t2);q[tot1].id=i;
}
else
{
B[++tot2].u=min(t1,t2);B[tot2].v=max(t1,t2);B[tot2].id=i;
}
}
sort(B+1,B+tot2+1,Cmp1);
int l=1;
for(int i=1;i<=tot2;i++)
{
while((A[l].u<B[i].u||(A[l].u==B[i].u&&A[l].v<B[i].v))&&l<=m)
{
flag[A[l].id]=1;
l++;
}
if(A[l].u==B[i].u&&A[l].v==B[i].v)
{
Del[B[i].id]=A[l].id;l++;
}
if(l==m+1)
break;
}
while(l<=m)
{
flag[A[l].id]=1;l++;
}
int num=0;
sort(A+1,A+m+1,Cmp3);
for(int i=1;i<=m;i++)
{
if(flag[A[i].id])
{
if(Find(A[i].u)!=Find(A[i].v))
{
int t=A[i].id;
num++;
Max[t+n]=t+n;v[t+n]=A[i].w;
Join(t+n,A[i].u);Join(t+n,A[i].v);
int root1=Find(A[i].u),root2=Find(A[i].v);
pre[root1]=root2;
}
if(num==n-1)
break;
}
}
sort(B+1,B+tot2+1,Cmp2);
sort(A+1,A+m+1,Cmp2);
int last=tot2;
for(int i=tot1;i>=1;i--)
{
while(B[last].id>q[i].id&&last)
{
int t=Del[B[last].id];
Split(A[t].u,A[t].v);
int tt=Max[A[t].v];
if(v[tt]>A[t].w)
{
Cut(tt,A[tt-n].u);Cut(tt,A[tt-n].v);
v[n+t]=A[t].w;Max[n+t]=n+t;
Join(n+t,A[t].u);Join(n+t,A[t].v);
}
else last--;
}
Split(q[i].u,q[i].v);
Ans[i]=v[Max[q[i].v]];
}
for(int i=1;i<=tot1;i++)
printf("%d\n",Ans[i]);
return 0;
}