您的位置:首页 > 其它

bzoj1984 月下“毛景树”

2017-09-30 06:56 302 查看
传送门

果然强校出的题都有坑= =

好吧其实是我太弱

都知道化边权为点权了还没发现链上查询和修改时的坑

知道了这个这题就是板子题了= =

CODE:

#include<cstdio>
#include<vector>
using namespace std;
#define N 100005
struct tree
{
int num,change,plus;
}t[N<<2];
int f
,deep
,size
,son
,top
,pos
,s
,point
,num
;
char str[10];
int n,m,x,y,z,tot;
vector<int> v
,w
,id
;
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<<
10bf1
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;
}


发这题的题解就是为了提醒自己:一定要随时注意题目中的坑点以及出题人的良♂苦用心!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bzoj 树链剖分