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

关于dtoj 177 谐振之石的一些反思

题目如下:

谐振之石 - 题目详情 - 岱陌存理 (dtoj.team)

这题我没有出,先粘贴上题解代码。

// #include <bits/stdc++.h>// using namespace std;
// using ll = long long;
#include <bits/stdc++.h>
using namespace std;
using ll  = long long;// 求最大公约数
// int g(int a, int b) {
//     while (b) {
//         a %= b;
//         swap(a, b);
//     }
//     return a;
// }
int g(int a,int b){while(b){a%= b;swap(a,b);}return a;
}// void slv() {
//     int n;
//     cin >> n;//     vector<pair<int, int>> dp; // 存储 (GCD值, 区块右端点位置)
//     ll ans = 0;
void slv(){int n ;cin>>n;vector<pair<int,int>> dp;ll ans = 0;//     for (int i = 1; i <= n; ++i) {
//         int x;
//         cin >> x;//         vector<pair<int, int>> cur;
//         cur.push_back({x, i});
for(int i = 1;i <= n;i ++){int x;cin>>x;vector<pair<int,int>> cur;cur.push_back({x,i});// 基于i-1的结果更新
//         for (auto const& [v, p] : dp) {
//             int ngd = g(v, x);
//             // 如果新的GCD与当前区块的GCD不同, 创建新区块
//             if (ngd != cur.back().first) {
//                 cur.push_back({ngd, p});
//             }
//         }for (auto const& [v,p]:dp){int ngd = g(v,x);if (ngd != cur.back().first){cur.push_back({ngd,p});}}//         dp = cur;//         int lps = 0; // 上一个区块的右端点位置
//         // dp中位置是降序的, 反向遍历计算贡献dp = cur;int lps = 0;
//         for (int j = dp.size() - 1; j >= 0; --j) {
//             auto const& [v, p] = dp[j];
//             if (v > 1) {
//                 ans += (p - lps); // 区块长度为 p - lps
//             }
//             lps = p;
//         }
//     }
for (int j = dp.size() - 1;j >= 0 ; j --){auto const& [v,p] = dp[j];if (v > 1){ans += (p - lps);}lps = p;
}
}//     cout << ans << endl;
// }
cout << ans<<endl;
}// int main() {
//     ios::sync_with_stdio(0);
//     cin.tie(0);
//     cout.tie(0);//     slv();//     return 0;
// }
int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);slv();return 0;
}

这题用了一种比较灵活的dp方式,dp数组维护了dp_{i,j}表示枚举到j时,最大公因数能得到i,先从左到右进行类似于选与不选的gcd运算,可以把当前元素作为右端点加入cur数组,而加入方式分为两种:

1.最大公因数在原来数组中存在,那么此段数组能通过后面的枚举合并计算。

2.最大公因数在原来数组中不存在,那么此段数组并不能通过端点合并的方式进行计算,那么只能重新存一个最大公因数和右端点进入dp数组了。

把dp数组换成cur数组,把继承得到的所有【gcd,右端点】中gcd>1的加入答案。

感觉就是,通过合并gcd相同的子数组,从而实现了对gcd=1的子数组的剪枝,然后易得gcd运算是log的 所以时间复杂度是

O(nlog^2n)(求gcd和遍历了一个gcd数组构成了log^2

http://www.dtcms.com/a/495081.html

相关文章:

  • UniverSheets最新版本测试
  • JD-Eclipse 插件核心功能与安装指南
  • kafka与zero-copy
  • 上海建站模板平台做外贸网站渠道
  • QT-常用控件(多元素控件)
  • MFC + OpenCV 图像预览显示不全中断问题解决:GDI行填充详解
  • 家庭农场做网站网站排名做不上去
  • LWIP通讯之PHY芯片LAN8720引脚详解
  • YOLOv3 :目标检测的经典融合与创新
  • 数值计算-线性方程组的迭代解法
  • win设置
  • 基于波动率自适应的ETF动态止盈止损模型构建与优化
  • C++ 继承笔记
  • H20裸金属租赁:捷智算安全隔离,独立配置保障数据安全
  • 装饰公司怎么做网站建设asp网站视频教程
  • 商业综合体 BAS 楼宇自控系统 + 能效管理系统:双系统协同打造高效低碳运营标杆
  • sm2025 模拟赛22 (2025.10.17)
  • 矢量图形AI 2025软件百度网盘下载与安装步骤分享
  • 建筑公司网站作用支付商城网站制作
  • 多模态文档理解视觉token剪枝思路
  • 本文讲解什么是PD诱骗协议以及如何避免充电器功率不足导致充电器不充电问题
  • 洛谷 - 线段树详解 1 (超详细版)
  • uni-app 入门学习教程,从入门到精通,uni-app基础扩展 —— 详细知识点与案例(3)
  • 解决uniapp中showLoading与showToast相互覆盖问题
  • 网站建设的外国文献三星网上商城怎么取消订单
  • 电子商务网站的建设内容家庭装什么宽带最划算
  • 轮廓系数(一个异型簇的分类标准)
  • 把 1688 商品详情搬进 MySQL:PHP 爬虫全链路实战(2025 版)
  • python+uniapp基于微信小程序的个人物品租售系统
  • 中国(新疆)航空航天国防展--三款MEMS惯性导航系统解析