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

#D251010D. 未命名 10 (unnamed)

给定 \(n\) 和长度为 \(n\) 的正整数序列 \(a\)
定义一次操作为,选择一个数 \(a_i\) 和质数 \(p\),将 \(a_i\) 赋值为 \(a_i\times p\)\(\frac{a_i}{p}\),必须满足赋值后 \(a_i\) 为正整数。

定义区间 \(l,r\) 的代价 \(val(l,r)\) 为,使 \(a_l,a_{l+1},\cdots,a_r\) 全都相等的最小操作次数。

请求出 \(\sum_{l=1}^n \sum_{r=l}^n val(l,r)\),对 \(10^9+7\) 取模。

对于 \(100\%\) 的数据,\(1\le n\le 2\times 10^5\)\(1\le a_i\le 10^6\)

口胡题解:

先转化一下式子:

\[ans=\sum^{}_{p\in a}\sum^{n}_{l=1}\sum^{n}_{r=l}\sum^{\log_pV}_{k=0}f(l,r,p,k) \]

假设 \(b_i\)\(a_i\)\(p\) 次方,这有两个结论:

\[\min^{+∞}_{k=0}\sum^{n}_{i=1}|b_i-k|=\sum^{+∞}_{k=0}min(\sum^{r}_{i=l}[b_i\le k],\sum^{r}_{i=l}[b_i> k]) \]

\[\min(x,y)=\frac{x+y-|x-y|}{2} \]

那么其中 \(f\) 计算方法为:

\[f(l,r,p,k)=min(\sum^{r}_{i=l}[b_i\le k],\sum^{r}_{i=l}[b_i> k])\\ =\frac{r-l+1-|\sum^{r}_{i=l}[b_i\le k]-\sum^{r}_{i=l}[b_i> k]|}{2}\\ =\frac{r-l+1-|\sum^{r}_{i=1}([b_i\le k]-[b_i> k])-\sum^{l-1}_{i=1}([b_i\le k]-[b_i> k])|}{2} \]

我们设 \(sum_r=\sum^{r}_{i=1}([b_i\le k]-[b_i> k])\) 考虑在 \(p,k\) 确定的情况下,也就是 \(sum\) 确定的情况下快速计算 \(\sum^{n}_{l=1}\sum^{n}_{r=l}f(l,r,p,k)\).

考虑先对 \(sum\) 排序,前面的 \((r-l+1)\) 当成区间长度,这个求和是好做的,我们记为 \(len\),此时我们可以把式子变成:

\[\frac{len-\sum^{n}_{i=2}\sum^{i-1}_{j=1}sum_i-sum_j}{2} \]

换个方式,就是:

\[\frac{len-\sum^{n}_{i=1}sum_i\times(2i-1-n)}{2} \]

这样计算复杂度就降低了,考虑现在复杂度:发现是 \(O(Pn\log n\log V)\),其中 \(P\) 是质数个数,算出来不超过 \(8\times 10^4\),考虑优化。

接下来是真口胡了,我不知道具体怎么做。

看看怎么优化这个东西,因为每个数都由 \(O(\log V)\) 个质数构成,所以发现 \(sum_i\) 的非 \(-1\) 的变化次数是 \(O(\frac{n\log V}{P})\) 的。也就是说我们先给每个数 \(-i\),那么就只有 \(O(\frac{n\log V}{P})\) 个值了,那么直接找出所有的变化点,相当于把 \(sum_i\) 加权,接着做这个式子,现在复杂度就是 \(O(n\log^2V\log(\log\frac{n\log V}{P}))\),能过了。

官方题解:

每个质数分别计算,问题变成每次将一个数加 1 或减 1,使所有数都相等的最小操作次数。
可以发现变为中位数次数最小,考虑计算。
可能要自行脑补一档部分分,只有 \(01\) 怎么做?
那就是区间答案就是 \(min\) 0,1 的个数。

可以从前到后扫描线,将 0 看做 \(-1\),利用前缀和来计算。

用线段树可以做到 \(O(nlogn)\),但考虑每次前缀和的变化量为 1,可以开桶统计每种前缀和的个数,做到 \(O(n)\)

对于一般情况,枚举分界 \(x\) ,将 \(\le x\) 的数看做 \(0\),其余看做 \(1\),然后将所有 \(x\) 的答案加起来,可以发现这样是对的。

于是 \(a_i=2^k\) 就做完了,但对于一般情况,不能每次都 \(O(n)\) 计算。

发现非 \(0\) 数的总和是 \(nlogV\) 的,考虑如过以某个点为端点的区间中位数一定为零,那么可以直接计算,称这些位置是无效的。

设非 \(0\) 的数有 \(m\) 个,那么有效位置不超过 \(3m\) 个。

考虑如何求出有效的位置,枚举非零数,然后向左向右扩展,需要记录前后缀的某个最值。

std 实现的比较随意,时间复杂度没有仔细分析,但不超过 \(O(nlog^2V)\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5,P=1e9+7,i2=P+1>>1;
int n,ans,c[N],d[N<<1];
vector<int>p[N];
bool vis[N],ban[N];
inline int md(int x){return x>=P?x-P:x;
}
int calc(vector<pair<int,int> >&a,int lim){int res=0;for(int i=0,j,s;j=i,i<a.size();i=j+1){c[s=1]=(a[i].second>=lim?1:-1);while(j+1<a.size()&&a[j+1].first==a[j].first+1)++j,c[++s]=(a[j].second>=lim?1:-1);int cl=0,s1=0,s2=0,c1=0,c2=1;d[n]=1;for(int k=1;k<=s;++k){c[k]+=c[k-1],cl=md(cl+k);if(c[k]<c[k-1]){s1=(1ll*(P-c[k])*d[c[k]+n]+s1)%P;c1-=d[c[k]+n];s2=(1ll*(c[k]+P)*d[c[k]+n]+s2)%P;c2+=d[c[k]+n];}else{s2=(1ll*(P-c[k-1])*d[c[k-1]+n]+s2)%P;c2-=d[c[k-1]+n];s1=(1ll*(c[k-1]+P)*d[c[k-1]+n]+s1)%P;c1+=d[c[k-1]+n];}res=(1ll*(P-c[k])*c1+s1+1ll*(c[k]+P)*c2+P-s2+res+cl)%P;s2=md(s2+md(c[k]+P)),++d[c[k]+n],++c2;}for(int i=0;i<=s;++i)d[c[i]+n]=0;}res=1ll*res*i2%P;return res;
}
int solve(vector<pair<int,int> >&a){sort(a.begin(),a.end());int sz=a.size(),mx=1;for(int i=0,o=1e9;i<sz;++i){o=min(o,2*i-a[i].first);vis[a[i].first]=true,mx=max(mx,a[i].second);for(int j=a[i].first+1,ed=(i==sz-1)?n:a[i+1].first-1;j<=ed;++j){if(2*i-j+1<o)break;vis[j]=true;a.push_back(make_pair(j,0));}}for(int i=sz-1,o=-1e9;~i;--i){o=max(o,2*i-a[i].first);for(int j=a[i].first-1,ed=i?a[i-1].first+1:1;j>=ed;--j){if(2*i-j-1>o||vis[j])break;vis[j]=true;a.push_back(make_pair(j,0));}}sort(a.begin(),a.end());int res=0;for(int i=1;i<=mx;++i)res=md(res+calc(a,i));for(int i=0,j;j=i,i<a.size();i=j+1){while(j+1<a.size()&&a[j+1].first==a[j].first+1)++j;for(int k=i,w;k<=j;++k)if(a[k].second){w=(1ll*(a[i].first-1)*(n-a[k].first+1)+1ll*(n-a[j].first)*a[k].first-1ll*(a[i].first-1)*(n-a[j].first))%P;res=(1ll*w*a[k].second+res)%P;}}for(auto v:a)vis[v.first]=false;return res;
}
int main(){freopen("unnamed.in","r",stdin);freopen("unnamed.out","w",stdout);scanf("%d",&n);for(int i=1,x;i<=n;++i){scanf("%d",&x);p[x].push_back(i);}for(int i=2;i<=1000000;++i)if(!ban[i]){long long x=i;vector<pair<int,int> >tmp;for(int j=i;j<=1000000;j+=i)ban[j]=true;for(int j=1;x<=1000000;x*=i,++j)for(int k=x;k<=1000000;k+=x)if((k/x)%i)for(auto v:p[k])tmp.push_back(make_pair(v,j));if(!tmp.empty())ans=md(ans+solve(tmp));}printf("%d\n",ans);return 0;
}
http://www.hskmm.com/?act=detail&tid=28219

相关文章:

  • 【JAVA】从入门到放弃-01-HelloWorld - 指南
  • 离线应用程序
  • 2025表面瑕疵检测厂家TOP5推荐:表面瑕疵检测,薄膜瑕疵检测,瑕疵检测设备,瑕疵在线检测,铝箔瑕疵在线检测,外观瑕疵检测机,薄膜瑕疵检测仪,陶瓷膜瑕疵检测各种类型检测,精准高效的质量守护
  • 表格识别:不仅能识别文字,更能理解表格的结构和逻辑关系,实现输出可编辑、可分析的结构化数据
  • 同步FIFO
  • P13274 [NOI2025] 三目运算符
  • Microsoft Office不小心卸载或重装系统后,如何重新安装 ... - sherlock
  • HTTPS 抓包乱码怎么办?原因剖析、排查步骤与实战工具对策(HTTPS 抓包乱码、gzipbrotli、TLS 解密、iOS 抓包) - 实践
  • 使用JaCoCo进行代码覆盖率分析
  • 计算机视觉专家入选德国国家科学院
  • 2025 年工程管理软件/软件系统/软件App/软件平台/工程管理软件和验房系统公司/企业推荐榜:数字化转型下的实用选型指南
  • 【Java学习】【Java基础】--第1篇:入门Java和对面向对象的理解
  • solutions
  • 技术面:Spring (事务传播机制、事务失效的原因、BeanFactory和FactoryBean的关系)
  • 安装与配置MySQL 8 on Ubuntu,包括权限授予、数据库备份及远程连接
  • 04-最简单的字符设备驱动
  • 完整教程:手机可视化方案(针对浓度识别)
  • AI元人文系列文章:决策范式与无为而治
  • SAP导入证书
  • Kubernetes存储卷:保障有状态应用的数据持久化
  • MySQL的查询操作语法要点
  • 华为链路聚合配置
  • 手机adb 调试自己
  • 离线安装 mysql
  • what is a good parent
  • 2025 年公共/商场/学校/地铁/电影院/会所/机场/卫生间隔断厂家选购指南:优质厂商推荐与实用选择策略
  • 为什么不该用 Double 表示金额及解决方案
  • Windows开发环境安装备忘录
  • Vue.use(Vuex)
  • [Gym-100343E]Convex Permutominoes 题解