AcWing进阶算法课Level-4 第七章 基础算法

启发式合并
AcWing 2154. 梦幻布丁73人打卡
AcWing 3189. Lomsat gelral54人打卡
manacher算法
AcWing 3188. manacher算法92人打卡
最小表示法
AcWing 158. 项链58人打卡
构造
AcWing 516. 神奇的幻方40人打卡
AcWing 2268. 时态同步39人打卡
打表
AcWing 1412. 邮政货车20人打卡

代码

AcWing 2154. 梦幻布丁

//题意:长为n的序列,m次操作,操作1 x y将所有颜色x改为y,操作2询问当前有多少段颜色
//思路:每次暴力合并x到y需要枚举,复杂度O(n),考虑把短的合并到大的上,即可以合并y到x,反正结果是一样的,用f[x]表示颜色为x时实际上需要寻找的链的颜色,此时复杂度为logn。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;int c[maxn], f[maxn], ans;
int hd[maxn], nxt[maxn], st[maxn], sz[maxn];
void insert(int i, int x){if(!hd[i])st[i]=x;sz[i]++; nxt[x]=hd[i]; hd[i]=x;
}
void merge(int x, int y){for(int i=hd[x]; i; i=nxt[i])ans -= (c[i-1]==y)+(c[i+1]==y);for(int i=hd[x]; i; i=nxt[i])c[i]=y;nxt[st[x]]=hd[y], hd[y]=hd[x], sz[y]+=sz[x];hd[x]=st[x]=sz[x]=0;
}int main(){ios::sync_with_stdio(false);int n, m;  cin>>n>>m;for(int i = 1; i <= n; i++){cin>>c[i];  f[c[i]]=c[i];ans += c[i]!=c[i-1];insert(c[i], i);}for(int i = 1; i <= m; i++){int op;  cin>>op;if(op==2)cout<<ans<<"\n";else{int x, y;  cin>>x>>y;if(x==y)continue;if(sz[f[x]]>sz[f[y]])swap(f[x],f[y]);if(!sz[f[x]])continue;merge(f[x],f[y]);}}return 0;
}

AcWing 3189. Lomsat gelral

//题意:给出一棵 n 个结点的树,每个结点都有一种颜色编号,求该树中每棵子树里的出现次数最多的颜色的编号和。
//思路:dsu on tree,对树做轻重链剖分,先跑轻儿子,最后一遍跑重儿子的时候不用清空数组,复杂度降低为O(nlogn)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;LL c[maxn], ans[maxn];vector<int>G[maxn];
LL siz[maxn], son[maxn];
void dsu(int x, int fa){ //轻重链剖分siz[x] = 1;for(int to : G[x]){if(to==fa)continue;dsu(to,x);siz[x] += siz[to];if(siz[to]>siz[son[x]])son[x]=to;}
}LL cnt[maxn], tmp, tmpv, Son;
void add(int x, int fa, int val){//统计x节点的贡献cnt[c[x]] += val;if(cnt[c[x]]>tmpv)tmpv=cnt[c[x]],tmp=c[x];else if(cnt[c[x]]==tmpv)tmp +=c[x];for(int to : G[x]){if(to==fa)continue;if(to==Son)continue;//统计x节点的轻儿子时不统计重儿子add(to,x,val);}
}
void dfs(int x, int fa, int op){//遍历每个节点for(int to : G[x]){if(to==fa)continue;if(to!=son[x])dfs(to,x,0);//暴力统计轻边的贡献,op=0表示递归完成后消除对该点的影响}if(son[x])dfs(son[x],x,1), Son=son[x];//统计重儿子的贡献,不消除影响add(x,fa,1); Son=0;   //暴力统计所有轻儿子的贡献ans[x] = tmp;if(!op)add(x,fa,-1),tmp=0,tmpv=0;//消除对该点的影响
}int main(){ios::sync_with_stdio(false);int n;  cin>>n;for(int i = 1; i <= n; i++)cin>>c[i];for(int i = 1; i <= n-1; i++){int x, y;  cin>>x>>y;G[x].push_back(y);G[y].push_back(x);}dsu(1,0);dfs(1,0,0);for(int i = 1; i <= n; i++)cout<<ans[i]<<" ";return 0;
}

AcWing 3188. manacher算法

//题意:给出一个长为n的字符串,求它的最长回文子串长度
//思路:朴素做法为每次选定一个中心,向左右枚举判断回文串,复杂度O(n^2)。
//马拉车:在一个大的回文串内,[mid,r]与[l,r]是对称全等的,此时对于i属于[mid,r]且回文边界不超过大的回文串时,他的回文边界等价于p[2*mid-i],然后再对超过的部分重新暴力匹配,更新最靠右的大回文串。
//string会超时
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e7+1e6+10;
char s[maxn], t[maxn<<1];
int p[maxn<<1];//p[i]记录以字符s[i]为中心的最长回文子串向两边的扩展的长度
int main(){ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);scanf("%s", s); int slen=strlen(s);  t[0]='~'; t[1]='#';//~防止下标溢出for(int i=0,j=1; i<slen; i++)t[++j]=s[i],t[++j]='#';//把可能的奇数偶数长度化为奇数求解,对称中心一定是#int ans = 0, mid=0, r=0, tlen=strlen(t); //最大回文子串的中心和边界for(int i=1; i<tlen; i++){if(i<=r)p[i]=min(p[mid*2-i], r-i+1);//没有超过MX回文串边界时,可用对称性求解while(t[i-p[i]]==t[i+p[i]])p[i]++;//超过边界时,暴力匹配if(p[i]+i>r)r=p[i]+i-1, mid=i;//更新mid和r,保证r是最靠右的if(p[i]>ans)ans=p[i];//更新答案(因为含#,所以不用乘2)}cout<<ans-1<<"\n";return 0;
}

AcWing 158. 项链

//题意:给出两个字符串,判断他们串成环后是否等价,输出最小字典序表示法,n=1e6
//思路:如果两个字符串是等价的话,那么他们的最小表示肯定一样的,所以直接O(n)求最小表示即可
//最小表示法:朴素O(n^2)做法为每次比较i与j的循环同构,把当前比较到的位置记作k,每次遇到不一样的字符时便把大的跳过,然后重新令k=0开始比较。此时可以发现性质,当不一样时,如果s[i+k]>s[j+k],对于起点在[i,i+k]内的字符串s[i+p],都不可能优于s[j+p],所以可以直接跳到s[i+k-1]继续与s[j]比较,此时优化到O(n)。
#include<bits/stdc++.h>
using namespace std;string calc(string s){int n = s.size();  s += s;int i=0, j=1, k;  //双指针,匹配长度while(i<n && j<n){for(k=0; k<n&&s[i+k]==s[j+k]; k++);if(s[i+k]>s[j+k])i += k+1;else j += k+1;if(i==j)i++;}int ans = min(i,j);return s.substr(ans, n);
}int main(){ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);string a, b;  cin>>a>>b;string ta=calc(a), tb=calc(b);if(ta==tb)cout<<"Yes\n"<<ta<<"\n";else cout<<"No\n";return 0;
}

AcWing 516. 神奇的幻方

#include<iostream>
#include<cstring>
using namespace std;const int maxn = 50;
int a[maxn][maxn];int main(){memset(a,0,sizeof(a));//数组清零int n;  cin>>n;int x = 1, y = (n+1)/2, tot = n*n;//中间位置a[x][y] = 1;for(int k = 2; k <= tot; k++){if(x==1 && y!=n){a[n][y+1] = k;//注意k++x = n, y = y+1;continue;//x,y值改变了要continue}if(x!=1 && y==n){//条件看错a[x-1][1] = k;x = x-1, y = 1;continue;}if(x==1 && y==n){a[x+1][y] = k;x = x+1, y = y;continue;}if(x!=1 && y!=n){if(a[x-1][y+1]==0){a[x-1][y+1] = k;x = x-1, y = y+1;}else{a[x+1][y] = k;x = x+1, y = y;}continue;}}for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){cout<<a[i][j]<<" ";}cout<<'\n';}return 0;
}

AcWing 2268. 时态同步

//题意:给出一颗n个点的树(1e5),每条边有一个权值c, 每次操作可以令某个权值+1,求最少操作次数令根节点到每个叶节点路径上的权值和相等
//思路:容易发现,越靠近根节点的,调整代价越小。我们可以把节点深度类比成距离,题目即为求把所有叶子节点调整到同一高度,每次优先调整靠近根部的。先dfs一遍更新到最远叶节点的距离dis[x],再循环一遍更新调整其余子节点的距离跟它一样。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 5e5+10;struct node{int to,w;};
vector<node>G[maxn];
LL dis[maxn], ans;
void dfs(int x, int fa){for(auto y : G[x]){if(y.to==fa)continue;dfs(y.to,x);dis[x] = max(dis[x], dis[y.to]+y.w);//更新这棵子树根节点和最远叶子节点的距离}for(auto y : G[x]){if(y.to==fa)continue;ans += dis[x]-(dis[y.to]+y.w);//调整每个子节点到最远的距离,累加每次调整的代价}
}int main(){ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n, rt;  cin>>n>>rt;for(int i = 1; i < n; i++){int x,y,z;  cin>>x>>y>>z;G[x].push_back(node{y,z});G[y].push_back(node{x,z});}dfs(rt, 0);cout<<ans<<"\n";return 0;
}

AcWing 1412. 邮政货车

"""
题意:给出一个4*n的矩阵,从左上角出发,经过每个拐角,回到左上角,求总方案数。预备知识:哈密度路表示由一个点出发到另外一个点结束,要求经过图中所有的点的一条路(不能重复经过点)。哈密顿回路表示从一个点出发再回到此点,经过图中所有点的一条路(不能重复经过点)。思路:对于一个n*4的图求哈密顿回路的个数,用陈丹琦的插头dp。但是由于宽度只有4,所以有另外一种递推的方法,达到优化的目的。
f[i]表示前i列中,第i列的第一个格子到第二个格子的哈密度路的条数
g[i]为前i列中,第i列的第一个格子到第四个格子的哈密顿路的条数f[i]分两类,g[i]分四类讨论后有递推公式:
f[i]=f[i-1]+g[i-1],g[i]=f[i-1]+f[i-1]+g[i-1]+g[i-2]-g[i-3]
高精度用py
"""
f = [0 for i in range(2001)]
g = [0 for i in range(2001)]
g[1] = 2; g[2] = 2; g[3] = 8;
f[1] = 0; f[2] = 2; f[3] = 4;n = int(input())
for i in range(4,n+1):g[i]=f[i-1]*2+g[i-1]+g[i-2]-g[i-3];f[i]=f[i-1]+g[i-1];
print(f[n])

AcWing进阶算法课Level-4 第七章 基础算法相关推荐

  1. 算法设计与分析第七章分支限界算法(完结篇)

    算法设计与分析第七章分支限界算法 一.分支界限算法概述 1.分支限界法类似于回溯法,是一种在问题的解空间树上搜索问题解的算法. 分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解 ...

  2. AcWing提高算法课Level-3 第六章 基础算法

    AcWing提高算法课Level-3 第六章 基础算法 位运算 AcWing 90. 64位整数乘法761人打卡 递推与递归 AcWing 95. 费解的开关520人打卡 AcWing 97. 约数之 ...

  3. 经典算法题每日演练——第七题 KMP算法

    原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...

  4. 视频教程-程序员必备算法课!(揭秘淘宝购物车算法)-机器学习

    程序员必备算法课!(揭秘淘宝购物车算法) CSDN讲师名下集合了诸多业界知名讲师的公开课内容,内容涵盖人工智能.大数据.区块链等诸多热门技术领域的最佳技术实践,聚合美团.滴滴.AWS.科大讯飞等知名企 ...

  5. yxc_第一章 基础算法(三)_区间合并

    截止2022.1.19,y总的基础算法网课已经全部听完.明天上午开始学习数据结构. 接下来还剩:第一章其他剩余的打卡题目.解决完这个问题之后,y总第一章基础算法就算暂时告一段落了. 未来算法学习的路还 ...

  6. 《实用机器学习》(孙亮 黄倩.著)笔记——第七章 推荐算法基础

    一.推荐算法基础 两类基本对象:1.用户(user):2.商品(item) 除了用户-商品的交互信息外,其他可以利用的数据包括: (1)商品的信息,包括商品的价格.类型等: (2)用户的信息,如用户的 ...

  7. 算法设计与分析第3章 贪心算法

    第4章 贪心算法 贪心算法总是作出在当前看来最好的选择.也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择. 贪心算法的基本要素 1.贪心选择性质 所谓贪心选择性质是指所 ...

  8. 九章基础算法04:二叉搜索树与哈希表

    目录 1. 什么是二叉搜索树 1.1 二叉搜索树结构 1.2 二叉搜索树特性应用 2. 二叉搜索树基础实现 2.1 BST类型与构造函数 2.2 插入操作 2.2.1 思路分析 2.2.2 递归实现 ...

  9. vtk教程第六章 基础算法

    我们已经了解了如何表示基本类型的可视化数据,如图像数据.结构化网格.非结构化网格和多边形数据.本章探讨了将这些数据转换为这些不同表示形式的方法,最终生成我们可以渲染的图形原语.这些方法被称为算法,并且 ...

最新文章

  1. 关于Oracle full outer join 的bug问题分析及处理
  2. SAE取消每日免费云豆赠送机制
  3. 外卖和快递行业数据_下周一起,整治全面启动!锁定全市外卖、快递行业!
  4. Oracle小知识总结
  5. android dialog 自定义布局,如何设置AlertDialog的自定义布局?
  6. Javascript、Dom、JQuery
  7. android关机背景,鍵盤消失后的Android白色背景
  8. 【C语言】通过原子操作实现加减乘除操作Ⅱ
  9. JS报错:Cannot read property 'type' of undefined
  10. 20天涨幅600%!深交所:天山生物或涉嫌新型股价操纵行为
  11. The single product is priced at about 1350 yuan
  12. ThreadPoolExecutor运转机制详解
  13. 拿到窗口ID,为什么画的内容没有显示出来
  14. layerdate一款很好用日期插件
  15. React-笔记整理
  16. PeopleSoft基础知识整理
  17. tar 慢 加快_加快慢的Outlook 2007
  18. OkHttpClient简单封装
  19. MySQL事务——万字详解
  20. 虚拟云服务器的用途,云服务器的这几个用途你了解么?

热门文章

  1. NR Measurements-- 切换测量A1 A2 A3 A4 A5 B1 B2
  2. C#/Java 动态生成电子发票
  3. 大学物理复习3-功+动能定理
  4. htons(), ntohl(), ntohs(),htons()这4个函数
  5. Linux /tmp
  6. 制作Android手机开机动画的详细过程
  7. 某银行系统ACS认证之TACACS+认证方案
  8. 服务器主板能配固态硬盘吗,主板没有M.2接口能使用M.2固态硬盘吗【使用方法】...
  9. 数据结构学习——图书管理系统
  10. 收藏数据结构学习网站