博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【CodeForces】671 C. Ultimate Weirdness of an Array
阅读量:5933 次
发布时间:2019-06-19

本文共 2702 字,大约阅读时间需要 9 分钟。

【题目】

【题意】给定长度为n的正整数序列,定义一个序列的价值为max(gcd(ai,aj)),1<=i<j<=n,定义f(i,j)为移除序列i~j后剩余序列的价值,求Σf(i,j)。1<=n,ai<=2*10^5。

【算法】数论+线段树

【题解】要求所有区间的f(i,j),转化为,记ans[i]表示f(l,r)=i的区间数量,则ANS=Σi*ans[i],i=1~mx,mx=max(ai)。

求解ans[i]不方便,记h[i]表示f(l,r)<=i的区间数量,则ans[i]=h[i]-h[i-1],显然h[i]单调不减。

考虑x=mx时,h[x]=n*(n+1)/2(即所有区间)。当x=mx-1时,设数列中mx的倍数有k个,就需要满足所选区间包含至少k-1个mx的倍数。随着x的减少,逐个将不满足的区间删除,就可以得到所有h[x]。

如何实现删除不满足的区间?

记v[i]表示数列中所有i的倍数的位置,用vector存储为v[i][k],这一步甚至可以用O(n√n)的分解素因数实现。

如果(l,r)合法,那么(l,R),R>r也一定合法。所以记next[i]表示L=i,R>=next[i]的区间均合法,初始next[i]=i。

对于x,h[x]=Σ(n-next[i]+1),i=1~n。

每次x减少,需要删除不满足x的区间时,假设x的倍数的位置为b1,b2……bk,需要进行以下3种操作:

1.p>b2,next[p]=n+1

2.b1<p<=b2,next[p]=max(next[p],bk)

3.1<=p<=b1,next[p]=max(next[p],bk-1)。

容易发现,next[i]是一个单调不减的数组,那么以上3个操作都可以用线段树的区间覆盖实现,答案用区间求和实现。(套路:线段树区间取max只能在单调的前提下通过区间覆盖实现

具体而言,线段树参数需要维护max,min,delta,sum,当min>=x时直接return,当max<=x时直接修改。

复杂度O(n log n)。

#include
#include
#include
#include
#include
#define ll long longusing namespace std;int read(){ char c;int s=0,t=1; while(!isdigit(c=getchar()))if(c=='-')t=-1; do{s=s*10+c-'0';}while(isdigit(c=getchar())); return s*t;}const int maxn=200010;struct tree{
int l,r,mins,maxs,delta;ll sum;}t[maxn*4];int n,a[maxn];ll h[maxn];vector
v[maxn];int min(int a,int b){ return a
b?a:b;}void up(int k){ t[k].sum=t[k<<1].sum+t[k<<1|1].sum; t[k].mins=min(t[k<<1].mins,t[k<<1|1].mins); t[k].maxs=max(t[k<<1].maxs,t[k<<1|1].maxs);}void modify(int k,int x){t[k].delta=x;t[k].mins=t[k].maxs=x;t[k].sum=1ll*x*(t[k].r-t[k].l+1);}void down(int k){ if(t[k].delta){ modify(k<<1,t[k].delta); modify(k<<1|1,t[k].delta); t[k].delta=0; }}void build(int k,int l,int r){ t[k].l=l;t[k].r=r;t[k].delta=0; if(l==r){ t[k].maxs=t[k].mins=t[k].sum=l; } else{ int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); up(k); }}void fix(int k,int l,int r,int x){ if(l>r||t[k].mins>=x)return; if(l<=t[k].l&&t[k].r<=r&&t[k].maxs<=x){modify(k,x);return;} down(k); int mid=(t[k].l+t[k].r)>>1; if(l<=mid)fix(k<<1,l,r,x); if(r>mid)fix(k<<1|1,l,r,x); up(k);}int main(){ n=read(); int mx=0; for(int i=1;i<=n;i++){ a[i]=read(); for(int j=1;j*j<=a[i];j++)if(a[i]%j==0){ v[j].push_back(i); if(j*j!=a[i])v[a[i]/j].push_back(i); } mx=max(mx,a[i]); } build(1,1,n); for(int i=mx+1;i>=1;i--){ if(v[i].size()>=2){ fix(1,v[i][1]+1,n,n+1); fix(1,v[i][0]+1,v[i][1],v[i][v[i].size()-1]); fix(1,1,v[i][0],v[i][v[i].size()-2]); } h[i]=1ll*n*(n+1)-t[1].sum; } ll ans=0; for(int i=1;i<=mx;i++)ans+=1ll*(i-1)*(h[i]-h[i-1]); printf("%lld",ans); return 0;}
View Code

 

转载于:https://www.cnblogs.com/onioncyc/p/8076110.html

你可能感兴趣的文章
这款芯片1+1都算不准,但能解决很多大难题
查看>>
特朗普推翻美国ISP隐私政策 允许电信运营商销售用户数据
查看>>
Slack 的野心:企业版的 App Store?
查看>>
雅虎投资人开药方 引入战略投资人进行市值管理
查看>>
CIO如何成为合格管理者
查看>>
高新区以“大数据+大生态”推进“千园之城”建设
查看>>
尼泊尔将在珠峰峰顶提供免费WiFi服务
查看>>
真正的智能家居离我们还有多远
查看>>
Salesforce的Quip收购了一家游戏公司?原来是看上了团队!
查看>>
安防如何从“如何看得清”到“怎样看得明白
查看>>
传微信要开直播业务:主流社交工具全面杀入直播战场
查看>>
Silverlight+WCF 新手实例 象棋 WCF通讯跨域(十五)
查看>>
“智慧城市”提升桂林人生活品质
查看>>
网络安全初创企业Illumio融资1.25亿美元 摩根领投
查看>>
NB-IoT成为利器,物联网云服务平台如何卡位?
查看>>
倾角传感器原理及市场现状浅析
查看>>
数据中心围笼的7个最佳实践
查看>>
布局智能家居:海尔、三星渐行渐远 谁走对了方向?
查看>>
智能家居风越吹越烈 离我们还有多远?
查看>>
共建安全大生态——2016第十七届信息安全大会采风
查看>>