JZOJ4846【NOIP2016提高A组集训第5场11.2】行走
2016-11-02 20:28
399 查看
Description
Data Constraint
对于70%的数据保证 n <= 1000对于100%的数据保证 n,q <= 10^5,c_i,v_i <= 10^{18}
保证每次修改后的边权小于等于原来的边权且不会小于1
Solution
这是一道树链剖分的模板题。只要将所有书取个对数,计算一下即可。
代码
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const ll maxn=200005; int first[maxn],last[maxn],next[maxn],deep[maxn],a[maxn][2]; ll n,i,t,j,k,l,x,y,m,z,num,ans1,x2,y2,z2,value1[maxn],g[maxn*4],ans,d[maxn]; int dfn[maxn],top[maxn],son[maxn],size[maxn],b[maxn],fa[maxn]; double xx,value[maxn],f[maxn*4],c[maxn]; void lian(ll x,ll y,double z,ll z1){ last[++num]=y;next[num]=first[x];first[x]=num;value[num]=z;value1[num]=z1; } void dg(int x,int y){ ll t;fa[x]=y;size[x]++;deep[x]=deep[y]+1; for (t=first[x];t;t=next[t]){ if (last[t]==y) continue; c[last[t]]=value[t]; d[last[t]]=value1[t]; dg(last[t],x); size[x]+=size[last[t]]; if (!son[x] || size[son[x]]<size[last[t]])son[x]=last[t]; } } void dg1(int x){ int t;dfn[x]=++num;b[num]=x; if (son[x]) top[son[x]]=top[x],dg1(son[x]); for (t=first[x];t;t=next[t]){ if (last[t]==fa[x] || last[t]==son[x]) continue; top[last[t]]=last[t]; dg1(last[t]); } } void insert(int l,int r,int v){ int mid=(l+r)/2; if (l==r){ f[v]=c[b[l]]; g[v]=d[b[l]]; return; } insert(l,mid,v*2); insert(mid+1,r,v*2+1); f[v]=f[v*2]+f[v*2+1]; g[v]=g[v*2]*g[v*2+1]; } void change(int l,int r,int v,int x){ int mid=(l+r)/2; if (l==r){ f[v]=xx; g[v]=z; return; } if (mid>=x) change(l,mid,v*2,x); else change(mid+1,r,v*2+1,x); f[v]=f[v*2]+f[v*2+1]; g[v]=g[v*2]*g[v*2+1]; } void find(int l,int r,int v,int x,int y){ int mid=(l+r)/2; if (l>=x && r<=y){ z/=g[v]; xx-=f[v]; return; } if (l<=y && mid>=x) find(l,mid,v*2,x,y); if (mid<y && r>=x) find(mid+1,r,v*2+1,x,y); } int main(){ freopen("walk.in","r",stdin);freopen("walk.out","w",stdout); scanf("%lld%lld",&n,&m); for (i=1;i<n;i++){ scanf("%lld%lld%lld",&x,&y,&z); a[i][0]=x;a[i][1]=y; xx=log(z)/log(2); lian(x,y,xx,z),lian(y,x,xx,z); } dg(1,0);num=0;top[1]=1; for (i=1;i<n;i++) if (deep[a[i][0]]<deep[a[i][1]])swap(a[i][0],a[i][1]); d[1]=1; dg1(1); insert(1,n,1); if (n*m>10000000){ for (i=1;i<=m;i++){ scanf("%lld",&z); if (z==1){ scanf("%lld%lld%lld",&x,&y,&z); x2=x;y2=y;z2=z; xx=log(z)/log(2); while (top[x]!=top[y]){ if (deep[top[x]]>deep[top[y]]){ find(1,n,1,dfn[top[x]],dfn[x]); x=fa[top[x]]; }else{ find(1,n,1,dfn[top[y]],dfn[y]); y=fa[top[y]]; } } if (dfn[x]>dfn[y]) swap(x,y); if (dfn[x]<dfn[y]) find(1,n,1,dfn[x]+1,dfn[y]); if (xx<0) ans=0; else ans=z; printf("%lld\n",ans); }else{ scanf("%lld%lld",&x,&z); xx=log(z)/log(2); x=dfn[a[x][0]]; change(1,n,1,x); } } }else{ for (i=1;i<=m;i++){ scanf("%lld",&z); if (z==1){ scanf("%lld%lld%lld",&x,&y,&z); while (x!=y){ if (deep[x]>deep[y]) z/=d[x],x=fa[x]; else z/=d[y],y=fa[y]; } printf("%lld\n",z); }else{ scanf("%lld%lld",&x,&z); d[a[x][0]]=z; } } } }
相关文章推荐
- JZOJ 4845 【NOIP2016提高A组集训第5场11.2】寻找
- 【NOIP2016提高A组集训第5场11.2】行走
- 【JZOJ4845】【NOIP2016提高A组集训第5场11.2】寻找
- 【JZOJ4846】【NOIP2016提高A组集训第5场11.2】行走
- 【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳
- 4845. 【NOIP2016提高A组集训第5场11.2】寻找
- 【NOIP2016提高A组集训第5场11.2】夕阳
- 【NOIP2016提高A组集训第5场11.2】寻找
- JZOJ4847【NOIP2016提高A组集训第5场11.2】夕阳
- 4847. 【NOIP2016提高A组集训第5场11.2】夕阳
- JZOJ 4841【NOIP2016提高A组集训第4场】平衡的子集
- JZOJ 4824. 【NOIP2016提高A组集训第1场10.29】配对游戏
- JZOJ4854【NOIP2016提高A组集训第6场11.3】小澳的坐标系
- JZOJ4861【NOIP2016提高A组集训第7场11.4】推冰块
- JZOJ 4826. 【NOIP2016提高A组集训第2场10.30】小澳的葫芦
- 【JZOJ4882】【NOIP2016提高A组集训第12场11.10】多段线性函数
- 【JZOJ4886】【NOIP2016提高A组集训第13场11.11】字符串
- JZOJ4890. 【NOIP2016提高A组集训第14场11.12】随机游走
- JZOJ 4823. 【NOIP2016提高A组集训第1场10.29】小W学物理
- NOIP2016提高A组集训第1场【JZOJ4823】小W学物理