链接
m<2000
建虚树后暴力
维护虚树中两点间的实际点的个数 模拟即可
巨丑的代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
#define yes puts("YES")
#define no puts("NO")
#define err puts("-1")
#define ios ios::sync_with_stdio(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int maxn = 5e5 + 6;
const LL inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
LL qp(LL x,LL y)
{LL ans=1;x%=mod;while(y){if(y&1)ans=ans*x%mod;x=x*x%mod;y>>=1;}return ans;
}
LL inv(LL x)
{return qp(x,mod-2);
}//head
int lgN,n,m,op[maxn],dfn[maxn],b[maxn],u[maxn],v[maxn],k[maxn],dep[maxn],tot;
int fa[maxn][30];
VI G[maxn],fake[maxn];
void dfs(int u,int f)
{dep[u]=dep[f]+1;fa[u][0]=f;dfn[u]=++tot;for(int i=1; i<=lgN; i++){fa[u][i]=fa[fa[u][i-1]][i-1];}for(int v:G[u])if(v!=f){dfs(v,u);}
}
int anc[maxn],dp[maxn];
void dfs1(int u,int f)
{anc[u]=f;dp[u]=dp[f]+1;for(int v:fake[u]){dfs1(v,u);}
}
int LCA(int x,int y)
{if(dep[x]<dep[y])swap(x,y);for(int i=lgN; i>=0; i--){if(dep[fa[x][i]]>=dep[y])x=fa[x][i];}if(x==y)return x;for(int i=lgN; i>=0; i--){if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return fa[x][0];
}
int top,stk[maxn];
void append(int u)
{if(top<=1){stk[++top]=u;return;}int lca=LCA(u,stk[top]);if(lca==stk[top]){stk[++top]=u;return;}while(top>1&&dfn[lca]<=dfn[stk[top-1]]){fake[stk[top-1]].pb(stk[top]);top--;}if(lca!=stk[top]){fake[lca].pb(stk[top]);stk[top]=lca;}stk[++top]=u;
}
bool cmp(int a,int b)
{return dfn[a]<dfn[b];
}
int _,cnt;
LL w[maxn],a[maxn],num[maxn];
void upd(int i)
{int x=u[i],y=v[i];if(op[i]<=3){while(x!=y){if(dp[x]<dp[y])swap(x,y);///x->fa[x]if(op[i]==1){w[x]+=k[i];a[x]+=k[i];}else if(op[i]==2){w[x]^=k[i];a[x]^=k[i];}else{if(w[x]>=k[i]) w[x]-=k[i];if(a[x]>=k[i]) a[x]-=k[i];}x=anc[x];}if(op[i]==1){a[x]+=k[i];}else if(op[i]==2){a[x]^=k[i];}else{if(a[x]>=k[i])a[x]-=k[i];}return ;}LL ans=0;if(op[i]==4){while(x!=y){if(dp[x]<dp[y])swap(x,y);ans+=w[x]*(dep[x]-dep[anc[x]]-1)+a[x];x=anc[x];}ans+=a[x];printf("%lld\n",ans);return ;}if(op[i]==5){while(x!=y){if(dp[x]<dp[y])swap(x,y);if((dep[x]-dep[anc[x]]-1)&1)ans^=w[x];ans^=a[x];x=anc[x];}ans^=a[x];printf("%lld\n",ans);return ;}if(op[i]==6){LL mx=-inf,mn=inf;while(x!=y){if(dp[x]<dp[y])swap(x,y);if((dep[x]-dep[anc[x]]-1))mx=max(mx,w[x]),mn=min(mn,w[x]);mx=max(mx,a[x]),mn=min(mn,a[x]);x=anc[x];}mx=max(mx,a[x]);mn=min(mn,a[x]);printf("%lld\n",mx-mn);return ;}if(op[i]==7){ans=inf;while(x!=y){if(dp[x]<dp[y])swap(x,y);if((dep[x]-dep[anc[x]]-1))ans=min(ans,abs(w[x]-k[i]));ans=min(ans,abs(a[x]-k[i]));x=anc[x];}ans=min(ans,abs(a[x]-k[i]));printf("%lld\n",ans);return ;}
}
int main()
{for(scanf("%d",&_); _; _--){scanf("%d%d",&n,&m);cnt=tot=0;lgN=(int)log(n)/log(2)+1;for(int i=1; i<n; i++){int u,v;scanf("%d%d",&u,&v);G[u].pb(v);G[v].pb(u);}dfs(1,0);for(int i=1; i<=m; i++){scanf("%d%d%d",&op[i],&u[i],&v[i]);b[++cnt]=u[i];b[++cnt]=v[i];if(op[i]<=3||op[i]==7)scanf("%d",&k[i]);elsek[i]=0;}sort(b+1,b+1+cnt);cnt=unique(b+1,b+1+cnt)-b-1;sort(b+1,b+1+cnt,cmp);top=0;stk[++top]=1;for(int i=1; i<=cnt; i++)if(b[i]!=1)append(b[i]);while(top>1)fake[stk[top-1]].pb(stk[top]),top--;dfs1(1,0);for(int i=1; i<=m; i++){upd(i);}for(int i=1; i<=n; i++)G[i].clear(),fake[i].clear(),w[i]=a[i]=0;for(int i=1; i<=n; i++){for(int j=0; j<=lgN; j++)fa[i][j]=0;}}
}

Master of Data Structure 虚树相关推荐

  1. HDU - 6967 G I love data structure 线段树维护矩阵 + 细节

    传送门 文章目录 题意: 思路: 题意: 给你两个长度为nnn的数组a,ba,ba,b,你需要完成如下四种操作: 思路: 思路还是比较简单的,首先建一颗线段树,线段树中维护a,b,a2,b2,aba, ...

  2. hdu4217 Data Structure? 线段树

    题意:不解释了. 看了别人的博客才知道要这么用线段树,用的灵活. 线段树的节点s[k].n记录剩下节点的数目.当查找到s[k].l=s[k].r即叶子节点的时候,就取这个值,然后将s[k].n=0说明 ...

  3. leetcode 211. Add and Search Word - Data structure design Trie树

    题目链接 写一个数据结构, 支持两种操作. 加入一个字符串, 查找一个字符串是否存在.查找的时候, '.'可以代表任意一个字符. 显然是Trie树, 添加就是正常的添加, 查找的时候只要dfs查找就可 ...

  4. 【HDU - 4217 】Data Structure? (线段树求第k小数)

    题干: Data structure is one of the basic skills for Computer Science students, which is a particular w ...

  5. TRIE - Data Structure

    Introduction 介绍 Trie,又称单词查找树,是一种树形结构,用于保存大量的字符串.它的优点是:利用字符串的公共前缀来节约存储空间. Trie is an ordered tree dat ...

  6. 牛客多校1 - Infinite Tree(虚树+换根dp+树状数组)

    题目链接:点击查看 题目大意:给出一个无穷个节点的树,对于每个大于 1 的点 i 来说,可以向点 i / minvid[ i ] 连边,这里的 mindiv[ x ] 表示的是 x 的最小质因数,现在 ...

  7. [虚树][树状数组][lca] Jzoj P5908 开荒

    Description 题目背景: 尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门.他加入师门后发现有无穷无尽的师兄弟姐妹,这几天新副本开了,尊者神高达的师门作为一个 pve师门 ...

  8. BZOJ4912 SDOI2017天才黑客(最短路+虚树)

    容易想到把边当成点重建图跑最短路.将每条边拆成入边和出边,作为新图中的两个点,由出边向入边连边权为原费用的边.对于原图中的每个点,考虑由其入边向出边连边.直接暴力两两连边当然会被卡掉,注意到其边权是t ...

  9. 算法 | 虚树学习笔记

    虚树学习笔记? blog 虚树是一棵虚拟构建的树-废话 这棵树只包含关键点和关键的点,而其他不影响虚树结构的点和边都相当于进行了路径压缩-而且整棵虚树的大小不会超过关键点的2倍 举个例子? 比方说-4 ...

最新文章

  1. js取整、四舍五入等数学函数
  2. php str cmp,php中整数的strcmp equivalent(intcmp)
  3. java手动调用finalize_Java并手动执行finalize
  4. 远程登录工具 —— filezilla(FTP vs. SFTP)、xshell、secureCRT
  5. python自动化测试框架开发_webUI自动化测试框架(Python+selenium)
  6. .NetCore + NSwag生成可交互API文档
  7. shellscript 07 正则表达式介绍
  8. 构造Linux流媒体服务器收藏
  9. 个人博客升级改造ing
  10. 考计算机初级难不难,初级程序员好考吗_考试难不难_上学吧
  11. windows10中charles设置代理,android手机无法上网
  12. 13个医学图像 AI 入门项目- 都跑完你就超神了!
  13. Spring知识整合(主要SSM)
  14. 转载: 找不到MSVCR90.dll、Debug vs Release及cppLapack相关
  15. 网络口碑营销的优势和实施步骤
  16. 我们将迎来另一个 VR 寒冬吗?
  17. flutter 微信语言选择_#Flutter项目(3)之仿写微信通讯录界面
  18. CentOS7搭建私有化Docker仓库Harbor
  19. C#--如何用字符串组成的逻辑表达式进行判断,如:“7>2(4<7||8>4)“,字符串写的逻辑表达式来进行判断(只需3步)
  20. 个人一些学习python经历

热门文章

  1. matlab二阶滤波器设计,基于matlab的各类滤波器设计
  2. win7下怎么配置ODBC数据源
  3. [享学Jackson] 四、控制Jackson行为的特征们之JsonFactory.Feature、JsonGenerator.Feature、JsonParser.Feature
  4. HDU 4416 (后缀自动机)
  5. 监控神器普罗米修斯Prometheus安装配置
  6. 大数据Impala系列之初识Impala
  7. mysql pga_PGA的监控与调整
  8. 【opencv四】利用opencv读取显示视频
  9. 【Transformer专题】一、Attention is All You Need(Transformer入门)
  10. Linux RPM包安装、卸载和升级(rpm命令)详解