bzoj2594 水管局长数据加强版

这个题调了我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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
校园悬赏任务平台对字典管理、论坛管理、任务资讯任务资讯公告管理、接取用户管理、任务管理、任务咨询管理、任务收藏管理、任务评价管理、任务订单管理、发布用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行校园悬赏任务平台程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。校园悬赏任务平台的开发让用户查看任务信息变得容易,让管理员高效管理任务信息。 校园悬赏任务平台具有管理员角色,用户角色,这几个操作权限。 校园悬赏任务平台针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理任务信息,管理任务资讯公告信息等内容。 校园悬赏任务平台针对用户设置的功能有:查看并修改个人信息,查看任务信息,查看任务资讯公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看任务,删除任务操作,新增任务操作,修改任务操作。任务资讯公告信息管理页面提供的功能操作有:新增任务资讯公告,修改任务资讯公告,删除任务资讯公告操作。任务资讯公告类型管理页面显示所有任务资讯公告类型,在此页面既可以让管理员添加新的任务资讯公告信息类型,也能对已有的任务资讯公告类型信息执行编辑更新,失效的任务资讯公告类型信息也能让管理员快速删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值