记录编号 261367 评测结果 AAAAAAAAAA
题目名称 [HNOI 2016] 网络 最终得分 100
用户昵称 GravatarZXCVBNM_1 是否通过 通过
代码语言 C++ 运行时间 6.013 s
提交时间 2016-05-17 11:55:53 内存使用 30.93 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 100010
priority_queue<int> q[MAXN*4],qq[MAXN*4];
struct node
{
    int left,right;
}cc[MAXN];
struct NODE
{
    int left,right;
}tree[MAXN*4];
struct Lovelive
{
    int begin,end,next;
}edge[MAXN*2];
int cnt,Head[MAXN],lc,size[MAXN],s1[2*MAXN],s2[2*MAXN],s3[3*MAXN],type[2*MAXN],belong[MAXN],pos[MAXN],P[MAXN][17],deep[MAXN],n,SIZE,V[MAXN];
bool vis[MAXN];
void addedge(int bb,int ee)
{
    edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee)
{
    addedge(bb,ee);addedge(ee,bb);
}
int read()
{
    int s=0,fh=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    return s*fh;
}
void dfs1(int u)
{
    int i,v;
    vis[u]=true;size[u]=1;
    for(i=Head[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].end;
        if(vis[v]==false)
        {
            deep[v]=deep[u]+1;
            P[v][0]=u;
            dfs1(v);
            size[u]+=size[v];
        }
    }
}
void Ycl()
{
    int i,j;
    for(j=1;(1<<j)<=n;j++)
    {
        for(i=1;i<=n;i++)
        {
            if(P[i][j-1]!=-1)P[i][j]=P[P[i][j-1]][j-1];
        }
    }
}
void dfs2(int u,int chain)
{
    int k=0,i,v;
    pos[u]=++SIZE;belong[u]=chain;V[SIZE]=u;
    for(i=Head[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].end;
        if(deep[v]>deep[u]&&size[v]>size[k])k=v;
    }
    if(k==0)return;
    dfs2(k,chain);
    for(i=Head[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].end;
        if(deep[v]>deep[u]&&v!=k)dfs2(v,v);
    }
}
int LCA(int x,int y)
{
    int i,j;
    if(deep[x]<deep[y])swap(x,y);
    for(i=0;(1<<i)<=deep[x];i++);i--;
    for(j=i;j>=0;j--)if(deep[x]-(1<<j)>=deep[y])x=P[x][j];
    if(x==y)return x;
    for(j=i;j>=0;j--)
    {
        if(P[x][j]!=-1&&P[x][j]!=P[y][j])
        {
            x=P[x][j];
            y=P[y][j];
        }
    }
    return P[x][0];
}
/*void del(int k,int C)
{
    int val;
    while(1)
    {
        val=q[k].top();q[k].pop();
        if(val==C)break;
        tmp.push(val);
    }
    while(!tmp.empty()){q[k].push(tmp.top());tmp.pop();}
}*/
int Get_max(int num)
{
    while((!qq[num].empty())&&(q[num].top()==qq[num].top())){q[num].pop();qq[num].pop();}
    if(q[num].empty())return -1;
    return q[num].top();
    //if(q[num].empty())printf("-1\n");
    //else printf("%d\n",q[num].top());
}
void Build(int k,int l,int r)
{
    tree[k].left=l;tree[k].right=r;
    if(l==r)return;
    int mid=(l+r)/2;
    Build(k*2,l,mid);Build(k*2+1,mid+1,r);
}
void Change(int k,int l,int r,int C,int zs)
{
    if(l<=tree[k].left&&tree[k].right<=r)
    {
        if(zs==1)q[k].push(C);
        else qq[k].push(C);//del(V[tree[k].left],C);
        return;
    }
    int mid=(tree[k].left+tree[k].right)/2;
    if(r<=mid)Change(k*2,l,r,C,zs);
    else if(l>mid)Change(k*2+1,l,r,C,zs);
    else {Change(k*2,l,mid,C,zs);Change(k*2+1,mid+1,r,C,zs);}
}
int Query(int k,int lr)
{
    if(tree[k].left==tree[k].right)return Get_max(k);
    int mid=(tree[k].left+tree[k].right)/2;
    if(lr<=mid)return max(Get_max(k),Query(k*2,lr));
    else return max(Get_max(k),Query(k*2+1,lr));
}
void Solve_get(int x,int fa)
{
    while(belong[x]!=belong[fa])
    {
        //Get(1,pos[belong[x]],pos[x]);
        cc[++lc].left=pos[belong[x]];cc[lc].right=pos[x];
        x=P[belong[x]][0];
    }
    if(x!=fa){cc[++lc].left=pos[fa];cc[lc].right=pos[x];}//Get(1,pos[fa],pos[x]);
}
bool cmp(node aa,node bb){return aa.left<bb.left;}
int main()
{
    freopen("network_tenderRun.in","r",stdin);
    freopen("network_tenderRun.out","w",stdout);
    int m,i,bb,ee,lca,S1,S2,S3,num,j;
    n=read();m=read();
    memset(Head,-1,sizeof(Head));cnt=1;
    for(i=1;i<n;i++)
    {
        bb=read();ee=read();
        addedge1(bb,ee);
    }
    dfs1(1);Ycl();
    dfs2(1,1);
    Build(1,1,n);
    for(i=1;i<=m;i++)
    {
        type[i]=read();
        if(type[i]==0)
        {
            s1[i]=read();s2[i]=read();s3[i]=read();
            lca=LCA(s1[i],s2[i]);
            lc=0;
            if(lca!=s1[i]&&lca!=s2[i])
            {
                Solve_get(s1[i],lca);
                Solve_get(s2[i],lca);
            }
            else if(lca==s1[i])Solve_get(s2[i],lca);
            else Solve_get(s1[i],lca);
            cc[++lc].left=0;cc[lc].right=0;cc[++lc].left=n+1;cc[lc].right=n+1;
            sort(cc+1,cc+lc+1,cmp);
            for(j=1;j<=lc;j++)if((cc[j].right+1)<=(cc[j+1].left-1))Change(1,cc[j].right+1,cc[j+1].left-1,s3[i],1);
        }
        else if(type[i]==1)
        {
            num=read();
            S1=s1[num];S2=s2[num];S3=s3[num];
            lca=LCA(S1,S2);
            lc=0;
            if(lca!=S1&&lca!=S2)
            {
                Solve_get(S1,lca);
                Solve_get(S2,lca);
            }
            else if(lca==S1)Solve_get(S2,lca);
            else Solve_get(S1,lca);
            cc[++lc].left=0;cc[lc].right=0;cc[++lc].left=n+1;cc[lc].right=n+1;
            sort(cc+1,cc+lc+1,cmp);
            for(j=1;j<=lc;j++)if((cc[j].right+1)<=(cc[j+1].left-1))Change(1,cc[j].right+1,cc[j+1].left-1,S3,-1);
        }
        else
        {
            num=read();
            printf("%d\n",Query(1,pos[num]));
            /*while((!qq[num].empty())&&(q[num].top()==qq[num].top())){q[num].pop();qq[num].pop();}
            if(q[num].empty())printf("-1\n");
            else printf("%d\n",q[num].top());*/
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}