轻重链剖分+启发式合并专题

Codeforces-741D(Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths)

一棵根为1 的树,每条边上有一个字符(a-v共22种)。 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串。 求每个子树中最长的Dokhtar-kosh路径的长度。给你n个点构成的一棵树,树里面的每一条边有一个权值,求出每个子树里面能通过重排构成回文串的最大路径长度.

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10,M=2*N;
int h[N],e[M],ne[M],w[M],idx;
int n,id[N],L[N],R[N],o,son[N],sz[N],dep[N],dfn[N];
int d[N],f[1<<23],ans[N],flag;
void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dfs1(int u,int fa=0){dep[u]=dep[fa]+1;dfn[u]=++o,id[o]=u;sz[u]=1;L[u]=o;for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==fa)continue;d[j]=d[u]^w[i];//d[j]表示从根节点到j的结点状态dfs1(j,u);sz[u]+=sz[j];if(sz[son[u]]<sz[j])son[u]=j;}R[u]=o;
}
void upd(int u){if(f[d[u]])ans[u]=max(ans[u],f[d[u]]-dep[u]);for(int i=0;i<22;i++){int x=d[u]^(1<<i);if(f[x])ans[u]=max(ans[u],f[x]-dep[u]);}
}
void upd2(int j,int u){if(f[d[j]])ans[u]=max(ans[u],f[d[j]]+(dep[j]-dep[u])-dep[u]);for(int i=0;i<22;i++){int x=d[j]^(1<<i);if(f[x])ans[u]=max(ans[u],f[x]+(dep[j]-dep[u])-dep[u]);}
}
void cal(int u,int fa){upd(u);//先更新贡献f[d[u]]=max(f[d[u]],dep[u]);//把我自己插进去for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==son[u]||j==fa)continue;for(int x=L[j];x<=R[j];x++)upd2(id[x],u);//计算子树所有节点和我构成的贡献for(int x=L[j];x<=R[j];x++)f[d[id[x]]]=max(f[d[id[x]]],dep[id[x]]);//插入这颗子树的贡献}
}
void dfs(int u,int fa=0,int keep=0){for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==fa||j==son[u])continue;//先枚举轻儿子,不保留dfs(j,u,0);ans[u]=max(ans[u],ans[j]);}if(son[u]){//再计算重儿子,保留答案int j=son[u];dfs(j,u,1);ans[u]=max(ans[u],ans[j]);flag=j;}cal(u,fa);//计算跟u节点相关的答案flag=0;if(!keep)for(int i=L[u];i<=R[u];i++)f[d[id[i]]]=0;
}
signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;memset(h,-1,sizeof h);char c;for(int i=2,j;i<=n;i++)cin>>j>>c,add(j,i,1<<(c-'a')),add(i,j,1<<(c-'a'));dfs1(1);dfs(1);for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
}

阔力梯的树

在这里插入图片描述

用启发式合并写

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int n,sz[N];
long long f[N];
vector<int>g[N],son[N];
set<int>S[N];
void dfs(int u){sz[u]=1;S[u].insert(u);for(auto j:g[u]){dfs(j);if(sz[u]<sz[j])swap(sz[u],sz[j]),swap(S[u],S[j]),f[u]=f[j];//这里swap有一个坑点,f[j]是你最后要用的,已经记录好了的不要乱动,u用了j的set直接从f[j]就好了for(auto x:S[j]){auto it=S[u].lower_bound(x);if(it==S[u].begin())f[u]+=(x-*it)*(x-*it);else if(it==S[u].end())it--,f[u]+=(x-*it)*(x-*it);else{int r=*it;it--;int l=*it;f[u]-=(r-l)*(r-l);f[u]+=(x-l)*(x-l)+(x-r)*(x-r);}S[u].insert(x);}sz[u]+=sz[j];}
}signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;for(int i=2;i<=n;i++){int fa;cin>>fa;g[fa].push_back(i);}dfs(1);for(int i=1;i<=n;i++)cout<<f[i]<<'\n';
}

用树链剖分写

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int n,h[N],ne[N],e[N],idx;
int sz[N],id[N],L[N],R[N],o,son[N],ans[N];
set<int>S;
int f;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dsu(int u){sz[u]=1;L[u]=++o,id[o]=u;for(int i=h[u];~i;i=ne[i]){int j=e[i];dsu(j);if(sz[j]>sz[son[u]])son[u]=j;sz[u]+=sz[j];}R[u]=o;
}
void ins(int x){if(S.empty()){S.insert(x);return;}auto it=S.lower_bound(x);if(it==S.begin())f+=(x-*it)*(x-*it);else if(it==S.end())it--,f+=(x-*it)*(x-*it);else{int r=*it;it--;int l=*it;f-=(r-l)*(r-l);f+=(r-x)*(r-x)+(x-l)*(x-l);}S.insert(x);
}
void dfs(int u,int keep=0){for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==son[u])continue;dfs(j,0);}if(son[u])dfs(son[u],1);for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==son[u])continue;for(int k=L[j];k<=R[j];k++)ins(id[k]);}ins(u);ans[u]=f;if(!keep)f=0,S.clear();
}signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;memset(h,-1,sizeof h);for(int i=2;i<=n;i++){int fa;cin>>fa;add(fa,i);}dsu(1);dfs(1);for(int i=1;i<=n;i++)cout<<ans[i]<<'\n';
}

F. Strange Memory

在这里插入图片描述

#include<bits/stdc++.h>
// #define int long long
using namespace std;
const int N=2e5+10,M=1e6+5e5;
int n,h[N],e[N],ne[N],idx,a[N];
int L[N],R[N],id[N],o,sz[N],son[N];
int f[2][20][M];
long long ans;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dsu(int u,int fa=0){sz[u]=1;L[u]=++o;id[o]=u;for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==fa)continue;dsu(j,u);if(sz[j]>sz[son[u]])son[u]=j;sz[u]+=sz[j];}R[u]=o;
}
void ins(int u,int k=1){for(int i=0;i<20;i++){int x=u>>i&1;f[x][i][a[u]]+=k;}
}
void cal(int u,int need){for(int i=0;i<20;i++){int x=u>>i&1;ans+=(1ll<<i)*(f[x^1][i][a[u]^need]);}
}
void dfs(int u,int fa=0,int keep=0){for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==fa||j==son[u])continue;dfs(j,u,0);}if(son[u])dfs(son[u],u,1);ins(u);//先去递归,再插入我自己,不然会wafor(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==fa||j==son[u])continue;for(int x=L[j];x<=R[j];x++)cal(id[x],a[u]);for(int x=L[j];x<=R[j];x++)ins(id[x]);}if(!keep)for(int i=L[u];i<=R[u];i++)ins(id[i],-1);
}signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);memset(h,-1,sizeof h);cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<n;i++){int a,b;cin>>a>>b;add(a,b);add(b,a);}dsu(1);dfs(1);cout<<ans;
}

E. Blood Cousins Return

树上gcd(x,y)==x^y的个数,操作1,插入新节点a[x]=v,操作2,合并x和y子树,操作3,把a[x]->v

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
int n,m,p[N],sz[N],a[N];
ll ans;
vector<int>g[N];//g[i]表示i可能的答案,枚举i的约数存入进去
unordered_map<int,int>mp[N];
int find(int x){if(p[x]==x)return x;return p[x]=find(p[x]);
}
// a^b==gcd(a,b)有多少对
//a^b>=|a-b|>=gcd(a,b)void merge(int x,int y){x=find(x),y=find(y);if(x==y)return;if(sz[x]<sz[y])swap(mp[x],mp[y]),swap(sz[x],sz[y]);for(auto [k,v]:mp[y]){for(auto t:g[k])if(mp[x].count(t))ans+=(ll)mp[x][t]*v;}for(auto [k,v]:mp[y])mp[x][k]+=v;mp[y].clear();p[y]=x;sz[x]+=sz[y];
}
void so(int x){for(int d=1;d*d<=x;d++){if(x%d)continue;int i=d,j=x/i,y;y=x-i;if((x^y)==__gcd(x,y)&&y>0)g[x].push_back(y);y=x+i;if((x^y)==__gcd(x,y)&&y<=2e5)g[x].push_back(y);if(i==j)continue;y=x-j;if((x^y)==__gcd(x,y)&&y>0)g[x].push_back(y);y=x+j;if((x^y)==__gcd(x,y)&&y<=2e5)g[x].push_back(y);}
}
signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);// for(int i=1;i<=2e5;i++)so(i);for (int i = 1; i <= 200000; i++) {for (int j = i + i; j <= 200000; j += i) {if (gcd(j, i^j) == i)g[j].push_back(i^j);}}cin>>n>>m;for(int i=1;i<=n+m;i++)p[i]=i,sz[i]=1;for(int i=1;i<=n;i++)cin>>a[i],mp[i][a[i]]++;while(m--){int op,x;cin>>op;if(op==1){int v;cin>>x>>v;a[x]=v;mp[x][v]=1;}if(op==2){int y;cin>>x>>y;merge(x,y);}if(op==3){int v;cin>>x>>v;int u=find(x);for(auto t:g[a[x]])if(mp[u].count(t))ans-=mp[u][t];mp[u][a[x]]--;a[x]=v;for(auto t:g[a[x]])if(mp[u].count(t))ans+=mp[u][t];mp[u][a[x]]++;}cout<<ans<<'\n';}
}
#include<bits/stdc++.h>
// #define int long long
using namespace std;
const int N=3e5+10;
int n,m,a[N],p[N];
long long ans;
vector<int>g[N];
int find(int x){if(p[x]==x)return x;return p[x]=find(p[x]);
}
void init(){for(int i=1;i<=2e5;i++){for(int j=i+i;j<=2e5;j+=i){if(__gcd(j,i^j)==i)g[j].push_back(i^j);}}
}
unordered_map<int,int>mp[N];
signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);init();cin>>n>>m;for(int i=1;i<N;i++)p[i]=i;for(int i=1;i<=n;i++)cin>>a[i],mp[i][a[i]]=1;while(m--){int op,x,v;cin>>op>>x>>v;if(op==1)a[x]=v,p[x]=x,mp[x][v]=1;if(op==2){x=find(x),v=find(v);if(x!=v){if(mp[x].size()<mp[v].size())swap(mp[x],mp[v]);for(auto [a,c]:mp[v]){for(auto need:g[a])if(mp[x].count(need))ans+=(long long)c*mp[x][need];}for(auto [a,c]:mp[v])mp[x][a]+=c;// mp[v].clear();p[v]=x;}}if(op==3){int fa=find(x);int c=1;for(auto need:g[a[x]])if(mp[fa].count(need))ans-=c*mp[fa][need];mp[fa][a[x]]--;a[x]=v;for(auto need:g[a[x]])if(mp[fa].count(need))ans+=c*mp[fa][need];mp[fa][a[x]]++;}cout<<ans<<'\n';}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/140137.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据Flink(九十七):EXPLAIN、USE和SHOW 子句

文章目录 EXPLAIN、USE和SHOW 子句 一、EXPLAIN 子句 二、USE 子句

C++特性——引用与指针详解

文章目录 引用1. 引用的作用1.1 引用可以做函数参数&#xff1a;1.2 引用做函数返回值&#xff1a; 2 常引用3 引用和指针3.1 引用和指针在语法层面和底层的异同3.1 引用和指针的不同 引用 简单来说&#xff0c;引用就是给一个变量起一个别名。例如&#xff1a; int a 1; in…

阿里云云服务器实例使用教学

目录 云服务器免费试用 详细步骤 Xshell 远程连接 云服务器免费试用 阿里云云服务器网址&#xff1a;阿里云免费试用 - 阿里云 详细步骤 访问阿里云免费试用。单击页面右上方的登录/注册按钮&#xff0c;并根据页面提示完成账号登录&#xff08;已有阿里云账号&#xff09;…

vue 自定义指令 -- 指令的值

vue 自定义指令 – 指令的值 **创建 工程&#xff1a; H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day05\准备代码\05-自定义指令-指令的值 vue --vers…

k8s-13 存储之secret

Secret 对象类型用来保存敏感信息&#xff0c;例如密码、OAuth 令牌和 ssh key。 敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活 。 Pod 可以用两种方式使用 secret:作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里 当 kubelet 为 pod 拉…

HugeGraph 部署和Hubble1.0.0的数据导入Bug修复

背景 HugeGraph 安装部署了最新版本1.0.0&#xff0c;发现它的 Web 工具 Hubble 有一个大 Bug。数据导入的时候&#xff0c;配置节点属性映射这个选项时&#xff0c;下拉框只有一个选项&#xff0c;但实际上&#xff0c;元数据配置中的属性有3个&#xff0c;这个 Bug 是怎么产…

从零开始搭建第一个django项目

目录 配置环境创建 Django 项目和 APP项目组成  ‍子目录文件组成应用文件组成 配置 settings.py启动项目 数据表创建models.pyDjango-models的常用字段和常用配置 Django-admin 引入admin后台和管理员外键views.pyurls.pypostman接口测试 QuerySetInstance功能APIView 的概念…

java学生通讯录管理系统

设计要求 本课程设计&#xff0c;涉及输入输出、GUI设计、数据库操作等本课程重要概念和编程技能&#xff0c;全面巩固和加深学生对java程序设计的相关概念的理解&#xff0c;全面强化java编程技能&#xff0c;培养学生综合运用所学知识和技能分析问题和解决问题的能力。培养学…

python web开发(四): Bootstrap

1.初步了解 别人已经写好的CSS样式&#xff0c;我们可以直接引用 下载 Link-BootStrap 解压&#xff0c;并放入到当前项目中 引用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</tit…

chatglm2微调—ptuning

Freeze: 即参数冻结&#xff0c;对原始模型部分参数进行冻结操作&#xff0c;仅训练部分参数&#xff0c;以达到在单卡或不进行TP或PP操作&#xff0c;就可以对大模型进行训练。 P-Tuning: 在输入的embedding层前&#xff0c;将prompt转换为可学习的额外一层embedding层. P-T…

SQL数据库管理工具RazorSQL mac中文版特点与功能

RazorSQL mac是一款功能强大的SQL数据库管理工具&#xff0c;它支持多种数据库&#xff0c;包括MySQL、Oracle、Microsoft SQL Server、SQLite、PostgreSQL等。 RazorSQL mac 软件特点和功能 多种数据库支持&#xff1a;RazorSQL支持多种数据库&#xff0c;用户可以通过一个工…

【ELK 使用指南 3】Zookeeper、Kafka集群与Filebeat+Kafka+ELK架构(附部署实例)

EFLKK 一、Zookeeper1.1 简介1.2 zookeeper的作用1.3 Zookeeper的特点1.5 Zookeeper的数据结构1.6 Zookeeper的应用场景1.7 Zookeeper的选举机制&#xff08;重要&#xff09;1.7.1 第一次启动时1.7.2 非第一次启动时 二、Zookeeper集群部署2.1 安装前准备2.2 安装 ZookeeperSt…