bzoj1984 月下“毛景樹”

傳送門

果然強校出的題都有坑= =
好吧其實是我太弱
都知道化邊權爲點權了還沒發現鏈上查詢和修改時的坑
知道了這個這題就是板子題了= =

CODE:

#include<cstdio>
#include<vector>
using namespace std;
#define N 100005
struct tree
{
    int num,change,plus;
}t[N<<2];
int f[N],deep[N],size[N],son[N],top[N],pos[N],s[N],point[N],num[N];
char str[10];
int n,m,x,y,z,tot;
vector<int> v[N],w[N],id[N];
inline int max(const int &a,const int &b){return a>b?a:b;}
inline int min(const int &a,const int &b){return a<b?a:b;}
inline void swap(int &a,int &b){a^=b,b^=a,a^=b;}
inline int read()
{
    int n=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,c=getchar();
    return n;
}
inline bool getstring()
{
    char c=getchar();int p=0;
    while(c<'A'||c>'Z') c=getchar();
    str[0]=c,c=getchar();
    while(c>='a'&&c<='z') str[++p]=c,c=getchar();
    return str[0]!='S';
}
void dfs(int now,int fa,int depth)
{
    f[now]=fa,deep[now]=depth;
    size[now]=1;
    int tmp=0,top=v[now].size();
    for(int i=0,to=v[now][0];i<top;to=v[now][++i])
      if(to!=fa)
      {
        s[to]=w[now][i],point[id[now][i]]=to;
        dfs(to,now,depth+1);
        size[now]+=size[to];
        if(size[to]>tmp) tmp=size[to],son[now]=to;
      }
}
void dfs2(int now,int high)
{
    top[now]=high,pos[now]=++tot;
    num[tot]=s[now];
    if(son[now]) dfs2(son[now],high);
    int top=v[now].size();
    for(int i=0,to=v[now][0];i<top;to=v[now][++i])
      if(to!=f[now]&&to!=son[now]) dfs2(to,to);
}
inline void pushdown(int now)
{
    if(!t[now].change&&!t[now].plus) return;
    int s1=now<<1,s2=now<<1|1;
    if(t[now].change)
    {
        t[s1].change=t[s2].change=t[s1].num=t[s2].num=t[now].change;
        t[s1].plus=t[s2].plus=0;
        t[now].change=0;
    }
    if(t[now].plus)
    {
        t[s1].num+=t[now].plus,t[s2].num+=t[now].plus;
        t[s1].plus+=t[now].plus,t[s2].plus+=t[now].plus;
        t[now].plus=0;
    }
}
inline void update(int now)
{
    t[now].num=max(t[now<<1].num,t[now<<1|1].num);
}
void build(int l,int r,int now)
{
    if(l==r){t[now].num=num[l];return;}
    int mid=(l+r)>>1;
    build(l,mid,now<<1);
    build(mid+1,r,now<<1|1);
    update(now);
}
void add(int L,int R,int l,int r,int now,int num)
{
    if(L<=l&&r<=R){t[now].plus+=num,t[now].num+=num;return;}
    int mid=(l+r)>>1;
    pushdown(now);
    if(L<=mid) add(L,R,l,mid,now<<1,num);
    if(R>mid) add(L,R,mid+1,r,now<<1|1,num);
    update(now);
}
void change(int L,int R,int l,int r,int now,int num)
{
    if(L<=l&&r<=R){t[now].change=t[now].num=num,t[now].plus=0;return;}
    int mid=(l+r)>>1;
    pushdown(now);
    if(L<=mid) change(L,R,l,mid,now<<1,num);
    if(R>mid) change(L,R,mid+1,r,now<<1|1,num);
    update(now);
}
int ask(int L,int R,int l,int r,int now)
{
    if(L<=l&&r<=R) return t[now].num;
    int mid=(l+r)>>1,ans=0;
    pushdown(now);
    if(L<=mid) ans=ask(L,R,l,mid,now<<1);
    if(R>mid) ans=max(ans,ask(L,R,mid+1,r,now<<1|1));
    return ans;
}
inline void addpath(int x,int y,int z)
{
    for(;top[x]!=top[y];x=f[top[x]])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        add(pos[top[x]],pos[x],1,n,1,z);
    }
    if(x==y) return;
    if(deep[x]>deep[y]) swap(x,y);
    int tmp=ask(pos[x],pos[x],1,n,1);
    add(pos[x],pos[y],1,n,1,z);
    change(pos[x],pos[x],1,n,1,tmp);
}
inline void changepath(int x,int y,int z)
{
    for(;top[x]!=top[y];x=f[top[x]])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        change(pos[top[x]],pos[x],1,n,1,z);
    }
    if(x==y) return;
    if(deep[x]>deep[y]) swap(x,y);
    int tmp=ask(pos[x],pos[x],1,n,1);
    change(pos[x],pos[y],1,n,1,z);
    change(pos[x],pos[x],1,n,1,tmp);
}
inline int askpath(int x,int y)
{
    change(1,1,1,n,1,0);
    int ans=0;
    for(;top[x]!=top[y];x=f[top[x]])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        ans=max(ans,ask(pos[top[x]],pos[x],1,n,1));
    }
    if(x==y) return ans;
    if(deep[x]>deep[y]) swap(x,y);
    int tmp=ask(pos[x],pos[x],1,n,1);
    change(pos[x],pos[x],1,n,1,0);
    ans=max(ans,ask(pos[x],pos[y],1,n,1));
    change(pos[x],pos[x],1,n,1,tmp);
    return ans;
}
int main()
{
    n=read();
    for(int i=1;i<n;i++)
      x=read(),y=read(),z=read(),
      v[x].push_back(y),v[y].push_back(x),
      w[x].push_back(z),w[y].push_back(z),
      id[x].push_back(i),id[y].push_back(i);
    dfs(1,0,1),dfs2(1,1),build(1,n,1);
    while(getstring())
    {
        x=read(),y=read();
        if(str[1]=='h') change(pos[point[x]],pos[point[x]],1,n,1,y);
        else if(str[1]=='o') changepath(x,y,read());
        else if(str[1]=='d') addpath(x,y,read());
        else printf("%d\n",askpath(x,y));
    }
    return 0;
}

發這題的題解就是爲了提醒自己:一定要隨時注意題目中的坑點以及出題人的良♂苦用心!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章