奇怪的事情

P4114 Qtree1

生而为人 @ 2019-08-10 20:49:05

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N=100005;
vector <pair<int,int> > va[N<<1];
int n,dfn;
int dep[N], size[N] , top[N] , heavy_son[N] , fa[N] , id[N] , ys[N] , val[N] , ask1[N] , ask2[N];
int tr[N<<2];
char t[20];
void dfs1(int now)
{
    size[now]=1;
    heavy_son[now] = 0; size[0] = 0;
    for(int i=0 ; i<va[now].size() ; i++)
    {
        int to = va[now][i].first;
        if(to == fa[now]) continue;
        val[to]=va[now][i].second;
        fa[to] = now; dep[to] = dep[now] + 1;
        dfs1(to);
        size[now]+=size[to];
        if(size[heavy_son[now]] < size[to])
        heavy_son[now]=to;
    }
}
void dfs2(int now,int first)
{
    top[now]=first;
    id[now]=++dfn;
    ys[dfn]=now;
    if(!heavy_son[now])
    return;
    dfs2(heavy_son[now],first);
    for(int i=0;i<va[now].size();i++)
    {
        int to=va[now][i].first;
        if(to==fa[now])
        continue;
        if(to==heavy_son[now])
        continue;
        dfs2(to,to);
    }
}
void update(int k)
{
    tr[k]=max(tr[k<<1],tr[k<<1|1]);
    return;
}
void build(int k,int l,int r)
{
    if(l==r)
    {
        tr[k]=val[ys[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    update(k);
}
void change(int k,int l,int r,int pos,int x)
{
    if(l>r)
    return;
    if(l==r)
    {
        tr[k]=x;
        return;
    }
    int mid=(l+r)>>1;
    if(mid>=pos)
    change(k<<1,l,mid,pos,x);
    else
    change(k<<1|1,mid+1,r,pos,x);
    update(k);
}
int query(int k,int l,int r,int x,int y)
{
    if(l>r)
    return -1e7;
    if(x <= l && r <= y)
    return tr[k];
    int mid=(l+r)>>1;

   /* int ans = -1e7;
    if(x <= mid) ans = max( ans , query(k<<1,l,mid,x,y) );
    if(y  > mid) ans = max( ans , query(k<<1|1,mid+1,r,x,y) );
    return ans; */

  /*  if(y <= mid)
    return query(k<<1 , l , mid,x,y);
    else
    if(x > mid)
    return query(k<<1|1,mid+1,r,x,y);
    else
    return max(query(k<<1,l,mid,x,mid),query(k<<1|1,mid+1,r,mid+1,y));  */
}
int work(int x,int y)
{
    int tx=top[x],ty=top[y];
    int ans=-1e8;
    while(tx!=ty)
    {
        if(dep[tx]<dep[ty])
        tx^=ty,ty^=tx,tx^=ty,x^=y,y^=x,x^=y;
        ans=max(ans,query(1,1,n,id[tx],id[x]));
        x=fa[tx],tx=top[x];
    }
    if(dep[x]>dep[y])
    swap(x,y);
    ans=max(ans,query(1,1,n,id[x]+1,id[y]));
    return ans;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n-1;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        ask1[i]=x;
        ask2[i]=y;
        va[x].push_back(make_pair(y,z));
        va[y].push_back(make_pair(x,z));
    }
    dep[1]=1;
    dfs1(1);
    dfs2(1,1);
    build(1,1,n);
    int x,y;
    while(1)
    {
        cin>>(t+1);
        if(t[1]=='D')
        break;
        cin>>x>>y;
        if(t[1]=='Q')
        {
            if(x==y)
            cout<<"0"<<endl;
            else
            cout<<work(x,y)<<endl;
        }
        if(t[1]=='C')
        {
            int a=ask1[x];
            int b=ask2[x];
            if(fa[a]==b) swap(a,b);
            change(1,1,n,id[b],y);
        }
    }
    return 0;
}

by 生而为人 @ 2019-08-10 20:50:29

关于线段树的第一种递归方法, 此题A了 关于线段树的第二种递归方法, 此题全MLE


by 生而为人 @ 2019-08-10 20:51:27

第一个注释掉的是第一种。

第二个注释掉的是第二种。


by 生而为人 @ 2019-08-10 20:53:05

@wlj_dy


by 生而为人 @ 2019-08-10 20:53:37

@顾瑀丶


by 生而为人 @ 2019-08-10 20:54:04

@__wfx


by 流逝丶 @ 2019-08-10 20:58:37

你为嘛不@我


by Leianha @ 2019-08-10 20:59:51

因为您弟弟巨啊


by zh_dou @ 2019-08-10 21:01:24

你为嘛不 @我


by Leianha @ 2019-08-10 21:02:44

貌似是爆栈了


by Treaker @ 2019-08-11 07:51:35

@生而为人 机房惯例,不调树剖,再说板子都过不了?


| 下一页