事实证明Lvat_s就是一个sb。。。
这题调试了2天
其实死在了一个很明显的错误上面
在倒数第二个关于q的循环里,我写道:
if(reans>e[i].v){……}
此时i明明表示q好不好……
正确的写法是:
if(reans>e[ask[i].ans].v){……}
还是贴一下代码吧,跑得很慢(19104ms)
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m,q,f[100005]; void Read(int &x){ char ch; while((ch=getchar())<'0' || ch>'9'); x=ch-'0'; while((ch=getchar())>='0' && ch<='9')x=x*10+ch-'0'; } struct Node{ int v,mx,rev,id; Node *ch[2],*fa,*mxe; Node(int val,Node *fat); void Pushdown(); void Pushup(); }*root[1100005],*Null; Node::Node(int val,Node *fat){ ch[0]=ch[1]=Null; if(val)mxe=this; else mxe=Null; fa=fat; v=mx=val; rev=id=0; } void Node::Pushdown(){ if(rev){ if(ch[0]!=Null)ch[0]->rev^=1; if(ch[1]!=Null)ch[1]->rev^=1; swap(ch[0]->ch[0],ch[0]->ch[1]); swap(ch[1]->ch[0],ch[1]->ch[1]); rev=0; } } void Node::Pushup(){ mx=v; if(v)mxe=this; else mxe=Null; if(ch[0]!=Null && ch[0]->mx>mx){mx=ch[0]->mx;mxe=ch[0]->mxe;} if(ch[1]!=Null && ch[1]->mx>mx){mx=ch[1]->mx;mxe=ch[1]->mxe;} } int Notroot(Node *p){ return (p->fa->ch[0]==p)||(p->fa->ch[1]==p); } void Prepare(Node *p){ if(Notroot(p))Prepare(p->fa); p->Pushdown(); } void Rotate(Node *x,int kind){ Node *y=x->fa,*z=y->fa; y->ch[!kind]=x->ch[kind]; if(x->ch[kind]!=Null)x->ch[kind]->fa=y; x->fa=z; if(Notroot(y))z->ch[z->ch[1]==y]=x; y->fa=x; x->ch[kind]=y; y->Pushup(); x->Pushup(); } void Splay(Node *x){ Prepare(x); while(Notroot(x)){ Node *y=x->fa,*z=y->fa; if(!Notroot(y))Rotate(x,y->ch[0]==x); else { if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);} else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);} else if(y->ch[0]==x && z->ch[1]==y){Rotate(x,1);Rotate(x,0);} else {Rotate(y,0);Rotate(x,0);} } } } void Access(Node *x){ for(Node *y=Null;x!=Null;y=x,x=x->fa){Splay(x);x->ch[1]=y;x->Pushup();} } void Makeroot(Node *x){ Access(x); Splay(x); x->rev^=1; swap(x->ch[0],x->ch[1]); } void Link(Node *x,Node *y){ Makeroot(x); x->fa=y; } void Cut(Node *x,Node *y){ Makeroot(x); Access(y); Splay(y); if(y->ch[0]==x){y->ch[0]=Null;x->fa=Null;} } int GetMx(Node *x,Node *y){ Makeroot(x); Access(y); Splay(y); return y->mx; } Node *MxAddress(Node *x,Node *y){ Makeroot(x); Access(y); Splay(y); return y->mxe; } Node *GetNull(){ Node *p=new Node(0,Null); p->fa=p->ch[0]=p->ch[1]=p->mxe=p; p->v=p->mx=-2100000000; p->rev=p->id=0; return p; } Node *ToLct(int x){ return root[x]; } struct Edge{ int a,b,v,id,del; friend bool operator<(Edge a,Edge b){ return (a.a<b.a)||(a.a==b.a && a.b<b.b); } }e[1000005]; bool cmp1(Edge a,Edge b){ return a.v<b.v; } bool cmp2(Edge a,Edge b){ return a.id<b.id; } struct Ask{ int k,x,y,ans; }ask[100005]; int Div(int x,int y){ int l=1,r=m; while(l<=r){ int mid=(l+r)>>1; if(e[mid].a==x && e[mid].b==y)return mid; if(e[mid].a<x || (e[mid].a==x && e[mid].b<y)){l=mid+1;} else r=mid-1; } return (l+r)>>1; } int Find(int x){return x==f[x]?x:f[x]=Find(f[x]);} void Union(int x,int y){if(x<y)f[y]=x;else f[x]=y;} int main(){ freopen("2594.in","r",stdin); freopen("2594.out","w",stdout); Read(n);Read(m);Read(q); Null=GetNull(); for(int i=1;i<=m;i++){ Read(e[i].a);Read(e[i].b);Read(e[i].v); if(e[i].a>e[i].b)swap(e[i].a,e[i].b); } sort(e+1,e+m+1,cmp1); for(int i=1;i<=n;i++)root[i]=new Node(0,Null); for(int i=1;i<=m;i++){ e[i].id=i; root[i+n]=new Node(e[i].v,Null); } sort(e+1,e+m+1); for(int i=1;i<=q;i++){ Read(ask[i].k); Read(ask[i].x); Read(ask[i].y); if(ask[i].x>ask[i].y)swap(ask[i].x,ask[i].y); if(ask[i].k==2){ int sci=Div(ask[i].x,ask[i].y); ask[i].ans=e[sci].id; e[sci].del=1; } } sort(e+1,e+m+1,cmp2); for(int i=1;i<=n;i++)f[i]=i; int tot=0; for(int i=1;i<=m;i++){ root[i+n]->id=i; if(!e[i].del && Find(e[i].a)!=Find(e[i].b)){ Union(Find(e[i].a),Find(e[i].b)); Link(ToLct(e[i].a),ToLct(i+n)); Link(ToLct(e[i].b),ToLct(i+n)); tot++; if(tot==n-1)break; } } for(int i=q;i>=1;i--){ if(ask[i].k==1){ ask[i].ans=GetMx(ToLct(ask[i].x),ToLct(ask[i].y)); } else { Node *mx=MxAddress(ToLct(ask[i].x),ToLct(ask[i].y)); int reans=mx->mx; if(reans>e[ask[i].ans].v){ Cut(ToLct(e[mx->id].a),mx); Cut(ToLct(e[mx->id].b),mx); Link(ToLct(ask[i].x),ToLct(ask[i].ans+n)); Link(ToLct(ask[i].y),ToLct(ask[i].ans+n)); } } } for(int i=1;i<=q;i++){ if(ask[i].k==1)printf("%d\n",ask[i].ans); } return 0; }