【题解】CF1098E Fedya the Potter
Sol
先考虑那个
显然可以枚举右端点维护。一个右端点对应的
那么就可以在
考虑二分答案,二分
那么问题就变成了求
显然,对于
首先一个区间必须满足
如果
否则这个区间一定满足
把这些区间的贡献写出来:
用字母代替常量得
记
对于后面那一坨,记
类欧即可。
Code
//LYC_music yyds!
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0)
#define lowbit(x) (x&(-x))
#define int long long
using namespace std;
inline char gc()
{
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
int read()
{
int pos=1,num=0;
char ch=getchar();
while (!isdigit(ch))
{
if (ch=='-') pos=-1;
ch=getchar();
}
while (isdigit(ch))
{
num=num*10+(int)(ch-'0');
ch=getchar();
}
return pos*num;
}
void write(int x)
{
if (x<0)
{
putchar('-');
write(-x);
return;
}
if (x>=10) write(x/10);
putchar(x%10+'0');
}
void writesp(int x)
{
write(x);
putchar(' ');
}
void writeln(int x)
{
write(x);
putchar('\n');
}
const int N=1e6+10;
int sum[N],cnt[N],v[N],w[N],a[N],b[N],n,t,c[N],x,y,ans,now;
int f(int a,int b,int c,int n)
{
int ac=a/c,bc=b/c,m=(a*n+b)/c,n1=n+1,n21=n*2+1,res=0;
if (!a) return bc*n1;
else if (a>=c||b>=c)
{
res=n*n1/2*ac+bc*n1;
int now=f(a%c,b%c,c,n);
res+=now;
return res;
}
int now=f(c,c-b-1,a,m-1);
res=n*m-now;
return res;
}
int calc(int A,int B,int a,int b,int c)
{
// cout<<A<<' '<<B<<' '<<a<<' '<<b<<' '<<c<<endl;
if (A<0||B<0||c<0) return 0;
int s=min(A,c/a),t=min(B,c/b),p=a*s+b*t-c-1,r=(s+1)*(t+1);
if (p<0) return r;
int n=p/a;
return r-f(a,p-a*n+b,b,n);
}
int calc(int n,int m)
{
return m*(2*n-m+1)/2;
}
bool check(int x)
{
int res=0,j=0;
for (int i=1;i<=100000;i++)
if (c[i])
{
res+=calc(c[i],min(c[i],(x-1)/i));
if (i<j) res+=c[i]*(cnt[j-1]-cnt[i])+calc(c[i]-1,c[j]-1,i,j,x-(sum[j-1]-sum[i])-i-j-1);
while (j<=100000&&sum[j]-sum[i]<x)
if (i<++j) res+=calc(c[i]-1,c[j]-1,i,j,x-(sum[j-1]-sum[i])-i-j-1);
}
return res<now;
}
int val(int x)
{
return x*(x+1)/2;
}
signed main()
{
n=read();
for (int i=1;i<=n;i++)
{
int g=0,top=0,last=i+1;
a[++t]=read(); b[t]=i;
for (int j=t;j;j--)
{
if (!g||a[j]%g) v[++top]=g=__gcd(g,a[j]);
c[g]+=last-b[j]; last=w[top]=b[j];
}
for (t=0;top;) b[++t]=w[top],a[t]=v[top--];
}
for (int i=1;i<=100000;i++)
sum[i]=x+=c[i]*i,cnt[i]=y+=c[i];
now=(val(val(n))+1)/2;
int l=1,r=sum[100000];
while (l<=r)
{
int mid=(l+r)>>1;
if (check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
writeln(ans);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探