当前位置: 首页 > news >正文

赛前训练 12 extra 树上差分倍增

A

树上差分板子.

B

每个点只有一条出边的有向图可以看作树

基于上述结论,我们直接倍增维护 \(\min,\operatorname{sum}\) 即可.

实现
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define int long long
using namespace std;const int N=1e5+5,M=48;
int n,k;
vector<int> G[N];
int dp[N][M],mn[N][M],sum[N][M];void solve(int x){int m=k,cur=x,ansmn=1e18,anss=0;for(int j=34;j>=0;j--){if((1ll<<j)<=m){ansmn=min(ansmn,mn[cur][j]);anss+=sum[cur][j];cur=dp[cur][j];m-=(1ll<<j);}}cout<<anss<<' '<<ansmn<<'\n';
}signed main(){ios::sync_with_stdio(0);cin.tie(0);cin>>n>>k;memset(mn,0x3f,sizeof mn);for(int i=1,u;i<=n;i++){cin>>u,u++;dp[i][0]=u;}for(int i=1,w;i<=n;i++){cin>>w;mn[i][0]=sum[i][0]=w;}for(int j=1;j<=34;j++){for(int i=1;i<=n;i++){dp[i][j]=dp[dp[i][j-1]][j-1];mn[i][j]=min(mn[i][j-1],mn[dp[i][j-1]][j-1]);sum[i][j]=sum[i][j-1]+sum[dp[i][j-1]][j-1];}}for(int i=1;i<=n;i++)solve(i);return 0;
}

C

容易发现每个点前面第一个和它不互质的数组成的子串必须得分成一段,这个很显然可以双指针维护.

然后对于区间 \([l,r]\),我们可以暴力跳出有多少个区间,但这样是 \(\mathcal{O}(n)\) 的,考虑倍增加速即可.

实现
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define int long long
using namespace std;const int N=1e5+5,V=1e5,M=48;
int n,tot,q;
int a[N],p[N],st[N][M];
bool vis[N],ok[N];
vector<int> s[N];void shai(){for(int i=2;i<=V;i++){if(!vis[i]){p[++tot]=i;for(int j=i*2;j<=V;j+=i)vis[j]=1;}}for(int i=1;i<=tot;i++)for(int j=p[i];j<=V;j+=p[i])s[j].emplace_back(i);
}
int qry(int l,int r){int res=0;for(int j=34;j>=0;j--){if(st[l][j]<=r){l=st[l][j];res+=(1ll<<j);}}res++;return res;
}
bool add(int x){for(int i:s[x])if(ok[i])return 0;for(int i:s[x])ok[i]=1;return 1;
}
void del(int x){if(!x)return;for(int i:s[x])ok[i]=0;
}signed main(){ios::sync_with_stdio(0);cin.tie(0);cin>>n>>q;for(int i=1;i<=n;i++)cin>>a[i];shai();for(int i=1,j=0;i<=n;i++){del(a[i-1]);while(j<n&&add(a[j+1]))j++;st[i][0]=j+1;}st[n+1][0]=n+1;for(int j=1;j<=34;j++){st[n+1][j]=n+1;for(int i=1;i<=n;i++)st[i][j]=st[st[i][j-1]][j-1];}while(q--){int l,r;cin>>l>>r;cout<<qry(l,r)<<'\n';}return 0;
}

D

对于一个节点,考虑其子树内和子树外的情形.

如果子树内有和当前节点相同的种类,则子树外的全部都得 ban,那个节点的兄弟们也得 ban,只有它自己子树内的不用 ban.

子树外的呢?画个图可以知道,只有那个子树外的节点到当前节点路径上中间的要 ban,结合上一种情形,我们发现只需要把当前节点的子树 ban 掉即可.

上述操作可以把树拍成序列后完成,搞完后做一遍前缀和即可.

实现
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define int long long
using namespace std;const int N=2e5+5;
int n,ans,all;
int a[N],b[N],siz[N],cnt[N],tot[N],dfn[N],out[N],d[N],s[N];
vector<int> G[N];void dfs(int cur,int fa){siz[cur]=1;dfn[cur]=++all;int pre=cnt[a[cur]];cnt[a[cur]]++;for(int i:G[cur]){if(i==fa)continue;int tmp=cnt[a[cur]];dfs(i,cur);siz[cur]+=siz[i];if(tmp!=cnt[a[cur]]){d[1]++;d[dfn[i]]--;d[out[i]+1]++;}}out[cur]=all;if(cnt[a[cur]]-pre<tot[a[cur]]){d[dfn[cur]]++;d[out[cur]+1]--;}
}signed main(){ios::sync_with_stdio(0);cin.tie(0);cin>>n;for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];sort(b+1,b+n+1);int len=unique(b+1,b+n+1)-b-1;for(int i=1;i<=n;i++){a[i]=lower_bound(b+1,b+len+1,a[i])-b;tot[a[i]]++;}for(int i=1,u,v;i<n;i++){cin>>u>>v;G[u].push_back(v);G[v].push_back(u);}dfs(1,0);int ans=0;for(int i=1;i<=n;i++){s[i]=s[i-1]+d[i];if(!s[i])ans++;}cout<<ans;return 0;
}

总结

  • 两个小技巧:

    双指针:维护子串信息

    倍增:加速跳跃过程

  • 树上问题:

    与图的转化(单出边有向图)

    与序列的转化(dfn 序)

    画图、考虑子树外和子树内

以上.

http://www.gsyq.cn/news/24660.html

相关文章:

  • 机器人技术新前沿:自动驾驶路径规划算法解析
  • 嗣澳——扫,墨依奥——描,希伊桉——线
  • 如果这就是人类脑海的话 雪白纸上划出血红层层痕迹 不如杀死这些记忆
  • ChatGPT From Zero To Hero - LLM学习笔记(一) - 详解
  • 基于Java+SSM+Django数字工坊课程教学网站(源码+LW+调试文档+讲解等)/数字工坊/课程教学/网站链接/在线课程/学习资源/视频教程/教育平台/数字艺术/学习网站/课程资料/ - 详解
  • 深入理解 Java和Go语法和使用场景(指南十一) - 指南
  • 深入解析:【办公类-115-04】20250920职称资料上传03——压缩课题结题报告PDF的大小(控制在200MB以内)
  • 树状数组和线段树基础
  • PWN手的成长之路-20-cgpwn2
  • 2024长城杯决赛-溯源取证1
  • [Agent] ACE(Agentic Context Engineering)和Dynamic Cheatsheet学习笔记
  • 2025年9月模拟赛整合
  • Windows 10 合并扩展磁盘分区
  • 零基础Linux快速上手03
  • habse
  • P2214 [USACO14MAR] Mooo Moo S 解题笔记
  • P1854 花店橱窗布置 解题笔记
  • 读书日记1
  • 物理AI:智能自动化的下一个前沿
  • tryhackme-预安全-网络基础知识-局域网介绍-05
  • UML图与数据流图
  • 一文读懂Schnorr签名
  • 论DCT和IDCT的重要性,汇编SIMD版第一,此贴第二,就是这么狂 :-)
  • 这些SAP实施公司哪家强?国内比较好的SAP实施商推荐
  • 博士研究文档管理技术指南
  • 10/19
  • 10.11-10.18 一周总结
  • 10/19/2025 一周总结
  • AI元人文:跨学科视野下的人工智能伦理新范式
  • Rust 开发最佳实践(Rustlang Best Practices)