Codeforces Round #643 (Div. 2) 题解
Posted encodetalker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #643 (Div. 2) 题解相关的知识,希望对你有一定的参考价值。
A
猜一手不会经过很多次就会有(Min=0),然后写个暴力就好了。
ll calc(ll n,ll k)
{
ll ans=n;
while (k--)
{
int mn=10,mx=0;ll tmp=ans;
while (tmp)
{
int x=tmp%10;tmp/=10;
mn=min(mn,x);mx=max(mx,x);
}
if (!mn) return ans;
else ans+=mn*mx;
}
return ans;
}
int main()
{
int T=read();
while (T--)
{
ll n=readll(),k=readll();
printf("%lld
",calc(n,k-1));
}
return 0;
}
B
将序列从小到大排序之后能分组就分组。
int n,a[300300];
int main()
{
int T=read();
while (T--)
{
n=read();
rep(i,1,n) a[i]=read();
sort(a+1,a+1+n);
int ans=0,now=0;
rep(i,1,n)
{
now++;
if (now>=a[i])
{
now=0;ans++;
}
}
printf("%d
",ans);
}
return 0;
}
C
枚举(x),之后对于每个(y),合法的(z)都是区间([C,min(x+y-1,D)])中的数。
考虑先求出这个右边界的取值范围,再加上使(zin[C,D])的区间的贡献即可。
int calc(int x,int y,int zl,int zr)
{
int nowl=zl,nowr=x+y-1;
int ans=nowr-nowl+1;
ans=max(0,ans);ans=min(ans,zr-zl+1);
return ans;
}
int main()
{
int a=read(),b=read(),c=read(),d=read();
ll ans=0;
rep(i,a,b)
{
int x=i;
int L=calc(x,b,c,d),R=calc(x,c,c,d);
ans+=1ll*(R-L+1)*(L+R)/2;
int tmp=d-x+1;
if (tmp>=c) continue;
tmp=max(b,tmp);
if (tmp+1<=c)
{
ans+=1ll*(d-c+1)*(c-tmp);
}
}
printf("%lld
",ans);
}
D
构造序列(1,1,cdots ,1,m-(n-1)).之后询问的(k=m-n),正确性显然。
int main()
{
int n=read(),m=read();
if (m<n*2) {puts("NO");return 0;}
puts("YES");
rep(i,1,n-1) printf("1 ");
printf("%d
",m-(n-1));
printf("%d
",m-(n-1)-1);
}
E
介绍一个猎奇做法。
先只考虑add/remove操作,我们可以枚举终止状态时的高度(Hin[h_i,h_{i+1}]),那么(H)的(+1)或(-1)都只会引起两种操作的固定数量的操作次数发生变化,于是最优花费只会在区间的两个端点取到。
再考虑move操作,注意到如果使用了这一操作就会一直使用到底,也就是最终add/remove操作只会剩下至多一个,我们可以二分一个位置(h‘),使得若(Hleq h‘)则remove操作的次数(geq)add操作的次数。也就是此时只会有move和remove操作,变成了最开始的情况。(H>h‘)的也是类似的。
然后被三分哥按在地上摩擦
#define int long long
int n,a[100100];
ll A,R,M,s[100100];
ll calc(int goal,int p)
{
ll ca=1ll*goal*p-s[p],cr=s[n]-s[p]-1ll*(n-p)*goal;
ll ans=ca*A+cr*R;
ll cm=min(ca,cr);
ans=min(ans,max(0ll,(cr-cm)*R)+max(0ll,(ca-cm))*A+cm*M);
return ans;
}
ll solve(int vL,int vR,int p)
{
ll ans=min(calc(vL,p),calc(vR,p));
int l=vL,r=vR,pos=vL;
while (l<=r)
{
int mid=(l+r)>>1;
ll cr=s[n]-s[p]-1ll*mid*(n-p),ca=1ll*p*mid-s[p];
if (cr>=ca) {pos=mid;l=mid+1;}
else r=mid-1;
}
rep(i,-3,3)
if ((pos+i>=vL) && (pos+i<=vR)) ans=min(ans,calc(pos+i,p));
return ans;
}
signed main()
{
n=read();A=read();R=read();M=read();
rep(i,1,n) a[i]=read();
sort(a+1,a+1+n);
rep(i,1,n) s[i]=s[i-1]+a[i];
ll ans=4e18;
rep(i,1,n-1) ans=min(ans,solve(a[i],a[i+1],i));
printf("%lld
",ans);
return 0;
}
F
神必题
最naive的想法是按照每个质数去找,也就是每次询问一个(p^q),显然gg。
稍微思考一下发现只要找(sqrt n)的质数,并且可以将一些质数乘在一起询问,再在最后确定每个质数的次幂。但是貌似完成前一步就需要(22)次询问,依然不行。
继续往下考虑,注意到(N)至多只会有(9)个不同的质因子,我们可以留(5)次询问来处理次幂。剩下的(17)次询问可以全部用来处理小的质因数,笔者的写法可以处理(<683)的质因子。
那么对于比它还大的呢?此时若这个数有(leq 2)个这样的质因数,我们可以直接将答案( imes 2),而对于(3)个的情况,可以分情况讨论:
-
不再含有其它的质因子,那么最终答案(=8),可以直接(+7).
-
含有其它的质因子,那么这个质因子只能为(2),也就是最终答案(=16=2+7+7),我们仍然可以将之前得到的答案(+7).
综上所述,记处理小质因数得到的答案为(x),则返回(max(2x,x+7)).
int tot,pri[2002000];
ll maxd=1e18,maxd1=1e9;
bool nopri[2002000];
ll ask(ll x)
{
printf("? %lld
",x);fflush(stdout);
ll y;scanf("%lld",&y);
return y;
}
void sieve(int n)
{
rep(i,2,n)
{
if (!nopri[i]) pri[++tot]=i;
for (int j=1;j<=tot && i*pri[j]<=n;j++)
{
nopri[i*pri[j]]=1;
if (i%pri[j]==0) continue;
}
}
}
vi d;
int ok=1;
void solve()
{
d.clear();
int used=0;ll prod=1;
int lst=1;
rep(i,1,tot)
{
if (maxd/pri[i]<prod)
{
ll now=ask(prod);used++;prod=1;
assert(now>0);
if (now!=1)
{
ll tmp=now;
for (int j=lst;1ll*pri[j]*pri[j]<=tmp && j<i;j++)
{
if (tmp%pri[j]) continue;
while (tmp%pri[j]==0) tmp/=pri[j];
d.pb(pri[j]);
}
if (tmp!=1) d.pb(tmp);
}
if (used==17) break;lst=i;
}
prod*=pri[i];
}
int len=d.size();int ans=1;
if (len&1) d.pb(1);
for (int i=0;i<len;i+=2)
{
ll now=1;
int d1=d[i],d2=d[i+1];
while (maxd1/now>=d1) now*=d1;
if (d2!=1)
while (maxd/now>=d2) now*=d2;
ll tmp=ask(now);used++;
int c=0;
while (tmp%d1==0)
{
tmp/=d1;c++;
}
ans*=(c+1);
c=0;
if (d2==1) continue;
while (tmp%d2==0)
{
tmp/=d2;c++;
}
ans*=(c+1);
}
ans=max(ans+7,ans*2);
printf("! %d
",ans);fflush(stdout);
}
int main()
{
sieve(1000);
int T=read();
while (T--) solve();
return 0;
}
以上是关于Codeforces Round #643 (Div. 2) 题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #643 (Div. 2) 题解
Codeforces Round #643 (Div. 2) D. Game With Array(构造)
Codeforces Round #643 (Div. 2) D. Game With Array(构造)