[bzoj4127] Abs
2016-06-19 12:52
363 查看
链剖。线段树要记录区间内负数的个数,负数的最大值..
如果增加后能使负数变正的话就往下暴力更新。。。
时间复杂度O(nlog^2n)
View Code
如果增加后能使负数变正的话就往下暴力更新。。。
时间复杂度O(nlog^2n)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<cmath> #define ll long long using namespace std; const int maxn=100233; struct zs{ int too,pre; }e[maxn<<1];int tot1,last[maxn]; int lc[maxn<<1],rc[maxn<<1],sz[maxn<<1],mx[maxn<<1],num[maxn<<1],tot; ll sm[maxn<<1],add[maxn<<1],V,SM; int dfn[maxn],tim,st[maxn],top,pos[maxn],bel[maxn],v[maxn],sz1[maxn],dep[maxn],fa[maxn],len[maxn],rt[maxn]; int i,j,k,n,m,L,R; int ra,fh;char rx; inline int read(){ rx=getchar(),ra=0,fh=1; while((rx<'0'||rx>'9')&&rx!='-')rx=getchar(); if(rx=='-')fh=-1,rx=getchar(); while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh; } inline void upd(int x){ int l=lc[x],r=rc[x]; if(mx[l]==-1e9)mx[x]=mx[r]+add[r];else if(mx[r]==-1e9)mx[x]=mx[l]+add[l];else mx[x]=max(mx[l]+add[l],mx[r]+add[r]); if(mx[x]>=0)mx[x]=-1e9; sm[x]=sm[l]+sm[r],num[x]=num[l]+num[r]; } inline void pushdown(int x){ int l=lc[x],r=rc[x]; if(mx[l]==-1e9)sm[l]+=add[x]*sz[l]; else sm[l]+=add[x]*(sz[l]-num[l]-num[l]); if(mx[r]==-1e9)sm[r]+=add[x]*sz[r]; else sm[r]+=add[x]*(sz[r]-num[r]-num[r]); add[l]+=add[x],add[r]+=add[x], add[x]=0; } void build(int a,int b){ int x=++tot;sz[x]=b-a+1; if(a==b){ sm[x]=abs(v[st[a]]); if(v[st[a]]<0)mx[x]=v[st[a]],num[x]=1;else mx[x]=-1e9; return; } int mid=a+b>>1; lc[x]=tot+1,build(a,mid),rc[x]=tot+1,build(mid+1,b); upd(x); // printf(" %d--%d sm:%lld mx:%d\n",a,b,sm[x],mx[x]); } void insert(int x,int a,int b){ if(L<=a&&R>=b){ if(mx[x]==-1e9){sm[x]+=V*sz[x],add[x]+=V;return;} if(mx[x]+add[x]+V<0){sm[x]+=V*(sz[x]-num[x]-num[x]),add[x]+=V;return;} } if(a==b){ // printf("! %d %d\n",a,mx[x]); if(mx[x]+add[x]+V>=0)sm[x]=mx[x]+add[x]+V,mx[x]=-1e9,add[x]=num[x]=0; else add[x]+=V,sm[x]-=V; // printf(" %d %lld\n",mx[x],sm[x]); return; } if(add[x])pushdown(x); int mid=a+b>>1; if(L<=mid)insert(lc[x],a,mid); if(R>mid)insert(rc[x],mid+1,b); upd(x); // printf("ins: %d--%d sm:%lld mx:%d num:%d\n",a,b,sm[x],mx[x],num[x]); } void query(int x,int a,int b){ if(L<=a&&R>=b){SM+=sm[x];/*printf("%d--%d %lld\n",a,b,sm[x]);*/return;} if(add[x])pushdown(x); int mid=a+b>>1; if(L<=mid)query(lc[x],a,mid); if(R>mid)query(rc[x],mid+1,b); upd(x); } void dfs(int x){ sz1[x]=1,dep[x]=dep[fa[x]]+1; for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]) fa[e[i].too]=x,dfs(e[i].too),sz1[x]+=sz1[e[i].too]; } void dfs2(int x,int chain){ int mx=0,i; dfn[x]=++tim,pos[x]=tim-dfn[chain]+1, bel[x]=chain,st[++top]=x; for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&sz1[e[i].too]>sz1[mx])mx=e[i].too; if(!mx){ len[chain]=pos[x],rt[chain]=tot+1,build(1,top),top=0; return; }else dfs2(mx,chain); for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=mx)dfs2(e[i].too,e[i].too); } inline int getlca(int a,int b){ if(dep[bel[a]]<dep[bel[b]])swap(a,b); while(bel[a]!=bel[b]){ a=fa[bel[a]]; if(dep[bel[a]]<dep[bel[b]])swap(a,b); } return dep[a]<dep[b]?a:b; } void change(int a,int lca){ while(bel[a]!=bel[lca]){ L=1,R=pos[a],insert(rt[bel[a]],1,len[bel[a]]); a=fa[bel[a]]; } if(a!=lca)L=pos[lca]+1,R=pos[a],insert(rt[bel[a]],1,len[bel[a]]); } void query1(int a,int lca){//printf("Q %d %d\n",a,lca); while(bel[a]!=bel[lca]){ L=1,R=pos[a],query(rt[bel[a]],1,len[bel[a]]); a=fa[bel[a]]; } if(a!=lca)L=pos[lca]+1,R=pos[a],/*printf("L R: %d %d\n",L,R),*/query(rt[bel[a]],1,len[bel[a]]); } inline void insert(int a,int b){ e[++tot1].too=b,e[tot1].pre=last[a],last[a]=tot1; e[++tot1].too=a,e[tot1].pre=last[b],last[b]=tot1; } int main(){ n=read(),m=read(); for(i=1;i<=n;i++)v[i]=read(); for(i=1;i<n;i++)insert(read(),read()); dfs(1),dfs2(1,1);int id,lca,a,b; // for(i=1;i<=n;i++)printf("%d bel:%d\n",i,bel[i]);//return 233; while(m--){ id=read(),a=read(),b=read(),lca=getlca(a,b); if(id==1){ V=read(); if(!V)continue; change(a,lca),change(b,lca); L=R=pos[lca],insert(rt[bel[lca]],1,len[bel[lca]]); }else{ SM=0; query1(a,lca),query1(b,lca), L=R=pos[lca],query(rt[bel[lca]],1,len[bel[lca]]); printf("%lld\n",SM); }//puts(""); } return 0; }
View Code
相关文章推荐
- YUV格式说明
- 幻灯片ppt和pps的区别
- 【转】Parallels Desktop 11.2.0 破解版 最佳Mac虚拟机软件
- java网络编程
- songtaste资源下载程序
- JQuery 常用【7】上传组件
- 推荐一下最近写的小项目
- 数据结构——c语言描述 第二章(3) 双向链表
- 【转】parallels desktop 11 授权许可文件删除方法
- Ubuntu14.04+CPU+Tensorflow
- 如果你不幸得了肩周炎颈椎病,治疗方案
- 学习进度条
- Hibernate的缓存技术EhCache的配置
- cmake:install制作简单的安装脚本
- MVN 安装 JAR包
- python time模块
- 如果我来导演,《魔兽2》会这样拍……
- 数据库复习⑧
- 【深度学习笔记】深度学习用于图片的分类和检测总结
- Android技术揭秘之activity堆栈管理