贸易
来源:互联网 发布:排课系统程序源码 编辑:程序博客网 时间:2024/04/29 23:37
题目大意
一共有m个结点,每个结点有一个权值a[i]。初始n个结点练成一颗树,有若干操作每次操作要么把一个结点加入树中要么询问u到v的路径上,a[x]-a[y]的最大值(u到v存在方向,先经过y再经过x)。
m<=10^5
倍增
倍增维护最小值、最大值、正着走的答案和反着走的答案,为了实现方便可以定义个类型存储然后打一个merge函数。merge中通过两条路径的信息得到合并后路径的信息,最小值和最大值容易维护,正着走的答案为两部分正着走的答案和前一部分选择最小值后一部分选择最大值的差的最大值,反着走的答案类似。对于插入通过其祖先的信息暴力搞出其的倍增信息即可。
#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;struct dong{ int a,i,ia,ai;};const int maxn=100000+10;int f[maxn][20],d[maxn],h[maxn],go[maxn*2],next[maxn*2],a[maxn];dong g[maxn][20],xdl,gjx,zlt;int i,j,k,l,t,u,v,w,n,m,p,ans,tot,root;bool bz[maxn];void add(int x,int y){ go[++tot]=y; next[tot]=h[x]; h[x]=tot;}void link(int x,int y){ bz[x]=1; d[x]=d[y]+1; f[x][0]=y; g[x][0].i=min(a[x],a[y]); g[x][0].a=max(a[x],a[y]); g[x][0].ia=max(a[y]-a[x],0); g[x][0].ai=max(a[x]-a[y],0);}dong merge(dong a,dong b){ dong c; c.i=min(a.i,b.i); c.a=max(a.a,b.a); c.ia=max(max(b.a-a.i,max(a.ia,b.ia)),0); c.ai=max(max(a.a-b.i,max(a.ai,b.ai)),0); return c;}void dfs(int x,int y){ link(x,y); int t=h[x]; while (t){ if (go[t]!=y) dfs(go[t],x); t=next[t]; }}int lca(int x,int y){ int j; if (d[x]<d[y]) swap(x,y); if (d[x]!=d[y]){ j=floor(log(d[x]-d[y])/log(2)); while (j>=0){ if (d[f[x][j]]>d[y]) x=f[x][j]; j--; } x=f[x][0]; } if (x==y) return x; j=floor(log(d[x])/log(2)); while (j>=0){ if (f[x][j]!=f[y][j]){ x=f[x][j]; y=f[y][j]; } j--; } return f[x][0];}dong get(int x,int y){ if (f[x][0]==y) return g[x][0]; int j=floor(log(d[x]-d[y])/log(2)); if (f[x][j]==y) j--; return merge(g[x][j],get(f[x][j],y));}int main(){ //freopen("trade.in","r",stdin); scanf("%d%d%d",&m,&n,&p); fo(i,1,m) scanf("%d",&a[i]); fo(i,1,n-1){ scanf("%d%d",&j,&k); root=j; add(j,k); add(k,j); } dfs(root,0); fo(j,1,floor(log(m)/log(2))) fo(i,1,m){ k=f[i][j-1]; f[i][j]=f[k][j-1]; g[i][j]=merge(g[i][j-1],g[k][j-1]); } while (p--){ scanf("%d%d%d",&t,&u,&v); if (t){ if (!bz[u]) swap(u,v); link(v,u); i=v; fo(j,1,floor(log(m)/log(2))){ k=f[i][j-1]; f[i][j]=f[k][j-1]; g[i][j]=merge(g[i][j-1],g[k][j-1]); } } else{ w=lca(u,v); if (v!=w){ xdl=get(v,w); swap(xdl.ia,xdl.ai); zlt=xdl; } if (u!=w){ gjx=get(u,w); zlt=gjx; } if (u!=w&&v!=w) zlt=merge(gjx,xdl); printf("%d\n",zlt.ia); } }}
0 0
- 贸易
- 贸易收支
- 贸易战争
- 最优贸易
- 最优贸易
- 最优贸易
- 最优贸易
- 最优贸易
- 日中贸易用语
- 日中贸易用语
- 技术还是贸易商业
- 了解一下版权贸易
- 加工贸易操作流程
- 个人如何做贸易?
- 新手如何做贸易
- 主要贸易术语
- trade 最优贸易
- 怎样做好网络贸易
- GNU C内嵌汇编学习笔记
- sql 查看创建几个数据库
- bzoj-1076[SCOI2008]奖励关
- git 教程
- java中的分代垃圾回收策略
- 贸易
- HDU 2119 Matrix(二分图最小边覆盖)
- bzoj-2434: [Noi2011]阿狸的打字机
- mybatis --- log4j配置
- Java 中的 Blocking 和 non-blocking IO 对比
- NYOJ-106-背包问题
- linux下安装jdk
- 矩阵的向量化及内积
- 面试问题01