ARC123
C - 1, 2, 3 - Decomposition
给定
-
之和为 。 -
在十进制下的每个数位均为 。
我怎么做出来这个题的?
我们考虑对每个答案
我们来处理
首先比较显然的:若
这之后,然后就会有位数
跑的非常快。实际上,
点击查看代码
#include<bits/stdc++.h> #define ll long long using namespace std; int read(){ int x=0,w=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*w; } ll n; bool check(ll x,int m){ if(x<m)return false; if(x>=m&&x<=3*m)return true; bool fl=false; for(int j=0;j<=m;j++) for(int i=x%10+(x%10<m?10:0);i<=3*m;i+=10) if(check((x-i)/10,j))return true; return false; } void solve(){ cin>>n;int ans; for(ans=1;!check(n,ans);ans++); printf("%d\n",ans); } int main(){ int T;cin>>T; while(T--)solve(); return 0; }
D - Inc, Dec - Decomposition
给出
-
, 。 -
单调不降。 -
单调不升。
试最小化
贪心结论:若
这似乎是十分显然的。
考虑令
然后呢?你发现就是一堆点到某个点的距离和的最小值,我们取中位数即可。
点击查看代码
#include<bits/stdc++.h> #define ll long long #define N 200010 using namespace std; ll read(){ ll x=0,w=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*w; } int n;ll a[N]; ll B,C,s[N<<1];int m; int main(){ n=read(); for(int i=1;i<=n;i++)a[i]=read(); B=a[1],C=0; s[++m]=B,s[++m]=C; for(int i=1;i<n;i++){ ll x=a[i+1]-a[i]; (x>=0)?B+=x:C-=x; s[++m]=B,s[++m]=C; } sort(s+1,s+1+m); ll ans=0; for(int i=1;i<=m;i++) ans+=abs(s[i]-s[n]); printf("%lld\n",ans); return 0; }
E - Training
给出
假设
设
若
-
, 。 -
, 。
我们只考虑第一种。
我们二分出
但是代码实现感觉好难写。
点击查看代码
#include<bits/stdc++.h> #define ll long long using namespace std; int read(){ int x=0,w=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*w; } ll f(ll a,ll b,ll c,ll n){ if(n<0)return 0; if(!a||!n)return (n+1)*(b/c); ll A=a/c,B=b/c; if(A||B)return n*(n+1)/2*A+B*(n+1)+f(a%c,b%c,c,n); ll M=(a*n+b)/c; return M*n-f(c,c-b-1,a,M-1); } ll calc(ll a,ll b,ll c,ll l,ll r){ return f(a,b,c,r)-f(a,b,c,l-1); } ll n,a,b,c,d; void solve(){ n=read(),a=read(),b=read(),c=read(),d=read(); if(b>d)swap(a,c),swap(b,d); ll l=1,r=n,mid; ll p1=-1,p2=n+1,p3=-1; while(l<=r){ mid=(l+r)>>1; if(mid*(d-b)>b*d*(c-a-1))r=mid-1,p1=mid; else l=mid+1; } if(p1==-1)return puts("0"),void(); l=p1,r=n; while(l<=r){ mid=(l+r)>>1; if(mid*(d-b)>b*d*(c-a))r=mid-1,p2=mid; else l=mid+1; } l=p2,r=n; while(l<=r){ mid=(l+r)>>1; if(mid*(d-b)<=b*d*(c-a+1))l=mid+1,p3=mid; else r=mid-1; } if(p3==-1)p3=p2-1; ll ans=0,k=calc(1,c*d,d,p1,p2-1)-calc(1,a*b,b,p1,p2-1); ans+=p2-p1-k; k=calc(1,a*b,b,p2,p3)-calc(1,c*d,d,p2,p3); ans+=p3-p2+1-k; printf("%lld\n",ans); } int main(){ int T=read(); while(T--)solve(); return 0; }
F - Insert Addition
对于序列
给定
然后进行
最后将
给定
我们考虑用系数来刻画这个东西,即用
求
假设已经找到位置
考虑
整除分块套类欧,这里是
在 SB Tree 上跳相同方向的链的时候要倍增,不然会起飞。这样时间复杂度是
点击查看代码
#include<bits/stdc++.h> namespace atcoder { namespace internal { // @param m `1 <= m` // @return x mod m constexpr long long safe_mod(long long x, long long m) { x %= m; if (x < 0) x += m; return x; } // @param n `n < 2^32` // @param m `1 <= m < 2^32` // @return sum_{i=0}^{n-1} floor((ai + b) / m) (mod 2^64) unsigned long long floor_sum_unsigned(unsigned long long n, unsigned long long m, unsigned long long a, unsigned long long b) { unsigned long long ans = 0; while (true) { if (a >= m) { ans += n * (n - 1) / 2 * (a / m); a %= m; } if (b >= m) { ans += n * (b / m); b %= m; } unsigned long long y_max = a * n + b; if (y_max < m) break; n = (unsigned long long)(y_max / m); b = (unsigned long long)(y_max % m); std::swap(m, a); } return ans; } } long long floor_sum(long long n, long long m, long long a, long long b) { assert(0 <= n && n < (1LL << 32)); assert(1 <= m && m < (1LL << 32)); unsigned long long ans = 0; if (a < 0) { unsigned long long a2 = internal::safe_mod(a, m); ans -= 1ULL * n * (n - 1) / 2 * ((a2 - a) / m); a = a2; } if (b < 0) { unsigned long long b2 = internal::safe_mod(b, m); ans -= 1ULL * n * ((b2 - b) / m); b = b2; } return ans + internal::floor_sum_unsigned(n, m, a, b); } } #define ll long long #define N 300010 using namespace std; ll read(){ ll x=0,w=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*w; } int a,b,n;ll l,r; int p[N],pcnt,mu[N];bool vis[N]; void init(){ mu[1]=1; for(int i=2;i<=n;i++){ if(!vis[i])p[++pcnt]=i,mu[i]=-1; for(int j=1;j<=pcnt&&i*p[j]<=n;j++){ vis[i*p[j]]=true; if(i%p[j]==0)break; mu[i*p[j]]=-mu[i]; } mu[i]+=mu[i-1]; } } ll calc(ll a,ll b){ ll ret=0; for(int l=1,r;l<=n;l=r+1){ r=n/(n/l); if(n/l<a+b)break; ret+=1ll*(mu[r]-mu[l-1])*atcoder::floor_sum(n/l/a,b,-a,n/l-a); } return ret; } int ans[N],cur; #define frac pair<ll,ll> #define fi first #define se second frac operator+(frac x,frac y){ return {x.fi+y.fi,x.se+y.se}; } frac operator*(ll x,frac y){ return {x*y.fi,x*y.se}; } ll val(frac x){ return 1ll*a*x.fi+1ll*b*x.se; } void ins(frac x){ ans[++cur]=val(x); } void solve2(frac x,frac y,ll l,ll r){ if(cur>=r-l+1)return; ll mid=val(x+y); if(mid>n)return; solve2(x,x+y,l,r); if(cur<r-l+1)ins(x+y); solve2(x+y,y,l,r); } void solve1(frac x,frac y,ll l,ll r){ if(cur>=r-l+1)return; ll a=val(x),b=val(y),mid=val(x+y); if(mid>n)return; ll cnt=calc(a,mid)+1; if(l==cnt){ ins(x+y); solve2(x+y,y,l,r); return; } if(l<cnt){ int dep=0; for(int i=20;~i;i--){ if(l<calc(a,val((dep+(1<<i))*x+y))+1) dep+=(1<<i); } solve1(x,dep*x+y,l,r); for(int i=dep;i;i--){ if(cur>=r-l+1)break; ins(i*x+y); solve2(i*x+y,(i-1)*x+y,l,r); } } else{ int dep=0;ll tot=calc(a,b); for(int i=20;~i;i--){ if(tot-l+1<calc(val(x+(dep+(1<<i))*y),b)+1) dep+=(1<<i); } cnt=tot-calc(val(x+dep*y),b); solve1(x+dep*y,y,l-cnt,r-cnt); } } int main(){ a=read(),b=read(),n=read(),l=read(),r=read(); init(); ll cnt=calc(a,b); if(l!=cnt+2&&r!=1) solve1({1,0},{0,1},max(l-1,1ll),min(r-1,cnt)); if(l==1)printf("%d ",a); for(int i=1;i<=cur;i++)printf("%d ",ans[i]); if(r==cnt+2)printf("%d ",b); printf("\n"); return 0; }
本文作者:SError
本文链接:https://www.cnblogs.com/SError0819/p/18077235
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步