【jzoj4846】【行走】【树链剖分】【线段树】
来源:互联网 发布:newman 网络引论 编辑:程序博客网 时间:2024/05/22 06:38
题目大意
解题思路
由于下取整不影响,用树链剖分维护边权积,超过最大值赋为最大值,用线段树单点修改区间查询。
code
#include<set>#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define LL long long#define LD double#define max(a,b) ((a>b)?a:b)#define min(a,b) ((a>b)?b:a)#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const inf=2147483647;int const maxn=100000,maxy=1000000001;int n,q,gra,tim,u[maxn+10],v[maxn+10],begin[maxn+10],size[maxn+10],heavy[maxn+10],dep[maxn+10],fa[maxn+10],belong[maxn+10],dfn[maxn+10],to[maxn*2+10],next[maxn*2+10];LL len[maxn*2+10],t[maxn*5+10];void insert(int u,int v,LL w){ to[++gra]=v; len[gra]=w; next[gra]=begin[u]; begin[u]=gra;}void dfs(int now,int pre){ size[now]=1; int mx=0; for(int i=begin[now];i;i=next[i]) if(to[i]!=pre){ dep[to[i]]=dep[now]+1; dfs(to[i],now); fa[to[i]]=now; size[now]+=size[to[i]]; if(size[to[i]]>mx){ mx=size[to[i]]; heavy[now]=to[i]; } }}LL maxv=1000000001;void change(int pos,int l,int r,int p,LL v){ if(l==r){ t[pos]=v; return; } int mid=(l+r)/2; if(p<=mid)change(pos*2,l,mid,p,v); else change(pos*2+1,mid+1,r,p,v); double tmp=double(t[pos*2])*double(t[pos*2+1]); if(tmp>maxv)t[pos]=maxv; else t[pos]=t[pos*2]*t[pos*2+1];}void dfss(int now,int pre,int v){ dfn[now]=++tim; change(1,1,n,dfn[now],v); for(int i=begin[now];i;i=next[i]) if(to[i]==heavy[now]){ belong[to[i]]=belong[now]; dfss(to[i],now,len[i]); } for(int i=begin[now];i;i=next[i]) if((to[i]!=pre)&&(to[i]!=heavy[now])){ belong[to[i]]=to[i]; dfss(to[i],now,len[i]); }}LL qury(int pos,int l,int r,int ll,int rr){ int mid=(l+r)/2; if((l==ll)&&(r==rr))return t[pos]; else if(rr<=mid)return qury(pos*2,l,mid,ll,rr); else if(mid<ll)return qury(pos*2+1,mid+1,r,ll,rr); else{ LL tmp1=qury(pos*2,l,mid,ll,mid),tmp2=qury(pos*2+1,mid+1,r,mid+1,rr); double tmp=double(tmp1)*double(tmp2); if(tmp>maxv)return maxv; else return tmp1*tmp2; }}LL lc(int u,int v,LL ans){ for(;u!=v;){ if(belong[u]==belong[v]){ if(dep[u]>dep[v])swap(u,v); LL tmp=qury(1,1,n,dfn[u]+1,dfn[v]); ans=(ans/qury(1,1,n,dfn[u]+1,dfn[v])); return ans; }else{ if(dep[belong[u]]<dep[belong[v]])swap(u,v); LL tmp=qury(1,1,n,dfn[belong[u]],dfn[u]); ans=(ans/qury(1,1,n,dfn[belong[u]],dfn[u])); if(!ans)return ans; u=fa[belong[u]]; } } return ans;}int main(){ freopen("walk.in","r",stdin); freopen("walk.out","w",stdout); scanf("%d%d",&n,&q); maxv=maxv*maxv; fo(i,1,n-1){ LL c;scanf("%d%d%lld",&u[i],&v[i],&c); insert(u[i],v[i],c);insert(v[i],u[i],c); } dep[1]=1;dfs(1,0); belong[1]=1;dfss(1,0,1); fo(i,1,q){ int type;scanf("%d",&type); if(type==1){ int x,y;LL v;scanf("%d%d%lld",&x,&y,&v); printf("%lld\n",lc(x,y,v)); }else{ int p;LL c;scanf("%d%lld",&p,&c); if(fa[u[p]]==v[p])change(1,1,n,dfn[u[p]],c); else change(1,1,n,dfn[v[p]],c); } } return 0;}
0 0
- 【jzoj4846】【行走】【树链剖分】【线段树】
- Jzoj4846 行走
- 【JZOJ4846】【NOIP2016提高A组集训第5场11.2】行走
- JZOJ4846【NOIP2016提高A组集训第5场11.2】行走
- 【行走】
- 行走
- 行走
- 行走
- 行走
- ”树链剖分+线段树“详解
- POJ3237 树链剖分+线段树
- BZOJ3924【树链剖分】【线段树】
- BZOJ4034【树链剖分】【线段树】
- poj3237Tree 【树链剖分+线段树】
- 树链剖分+线段树
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- Python基础-Dict 和 Set 类型
- Android进程和服务概念介绍
- 云PaaS向容器生态系统的演变之路
- 报表解决Excel导入数据不能根据显示值将实际值存入数据库的问题
- ActionBar相关实现详解
- 【jzoj4846】【行走】【树链剖分】【线段树】
- POJ 1002 487-3279(map)
- NOIP2013 写后感
- PAT 1006 Sign In and Sign Out
- 看zookeeper源代码庖丁解牛[还是写的很乱,自己看都看不懂了.]
- 在PaaS上构建SaaS应用程序时先搞清这些
- 高维宇宙 【NOIP2016提高A组集训第3场10.31】
- hiho 1412 : Rikka with Subsequence
- Mac安装MySQL