CF1471A

先从最简单的情况入手:数组中只有两个数 aaa 和 bbb。

令 a=cx+d,b=mx+k(0≤d,k<x)a=cx+d,b=mx+k(0\le d,k < x )a=cx+d,b=mx+k(0≤d,k<x)。

  • d,kd,kd,k 均为 000。不合并:c+mc+mc+m,合并:c+mc+mc+m
  • d,kd,kd,k 有一个为 000。不合并:c+m+1c+m+1c+m+1,合并:c+m+1c+m+1c+m+1
  • d,kd,kd,k 均不为 000,且 d+k≤xd+k\le xd+k≤x。不合并:c+m+2c+m+2c+m+2,合并:c+m+1c+m+1c+m+1
  • d,kd,kd,k 均不为 000,且 d+k>xd+k>xd+k>x。不合并:c+m+2c+m+2c+m+2,合并:c+m+2c+m+2c+m+2

综上,把两个数合并后对于答案的影响是只可能减少不可能增加,因此一次都不合并时答案取得最大值,全部合并时答案取得最小值。

代码如下:

/*_/      _/    _/_/_/      _/_/_/    _/_/_/_/_/    _/_/_/    _/_/_/_/    _/      _/  _/      _/  _/      _/
_/      _/  _/      _/  _/      _/      _/      _/      _/  _/      _/  _/      _/   _/    _/    _/    _/
_/      _/  _/      _/  _/              _/      _/      _/  _/      _/  _/      _/    _/  _/      _/  _/
_/      _/  _/_/_/_/_/  _/              _/      _/      _/  _/_/_/_/    _/  _/  _/      _/         _/_/_/  _/    _/          _/              _/      _/      _/  _/  _/      _/  _/  _/      _/        _/  _/_/_/     _/      _/  _/      _/      _/      _/      _/  _/    _/     _/_/_/_/       _/       _/    _/_/        _/_/_/      _/_/_/        _/        _/_/_/    _/      _/    _/  _/        _/      _/      _/*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define fo(i,x,y) for(register int i=x;i<=y;++i)
#define go(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;inline int read(){int x=0,fh=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-') fh=-1;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*fh;
}const int N=1e5+5;
int a[N]; void work(){ll sum=0,mx=0;int n=read(),x=read();fo(i,1,n) a[i]=read(),sum+=a[i];fo(i,1,n){mx+=a[i]/x;if(a[i]%x) mx++;}printf("%lld %lld\n",sum/x+(bool)(sum%x),mx);//puts("");
}
int main(){int T=read();while(T--){work();}return 0;
}

CF1471B

如果 x∣qx|qx∣q,设 t=qxt=\frac{q}{x}t=xq​,那么 qqq 会分裂成 xxx 个 ttt。而如果 x∣tx|tx∣t,那么这 xxx 个 ttt 又会分裂出 x2x^{2}x2 个 tx\frac{t}{x}xt​……很显然这是一个有终点的循环,每循环一次就会多出 xkx^{k}xk 个 qxk\frac{q}{x^{k}}xkq​。我们把当前循环中 qqq 分裂出的 xkx^{k}xk 个数看做 一个整体,每次循环都会使得数组里的元素和增加 qqq。同时,由于 q≤109q\le 10^{9}q≤109,所以循环次数为 O(log⁡xq)O(\log_{x}{q})O(logx​q),这是一个上界为 303030 的数,直接模拟这个循环即可。

代码如下:

/*_/      _/    _/_/_/      _/_/_/    _/_/_/_/_/    _/_/_/    _/_/_/_/    _/      _/  _/      _/  _/      _/
_/      _/  _/      _/  _/      _/      _/      _/      _/  _/      _/  _/      _/   _/    _/    _/    _/
_/      _/  _/      _/  _/              _/      _/      _/  _/      _/  _/      _/    _/  _/      _/  _/
_/      _/  _/_/_/_/_/  _/              _/      _/      _/  _/_/_/_/    _/  _/  _/      _/         _/_/_/  _/    _/          _/              _/      _/      _/  _/  _/      _/  _/  _/      _/        _/  _/_/_/     _/      _/  _/      _/      _/      _/      _/  _/    _/     _/_/_/_/       _/       _/    _/_/        _/_/_/      _/_/_/        _/        _/_/_/    _/      _/    _/  _/        _/      _/      _/*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define fo(i,x,y) for(register int i=x;i<=y;++i)
#define go(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;inline int read(){int x=0,fh=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-') fh=-1;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*fh;
}const int N=1e5+5;
int a[N],cnt[N];void work(){int n=read(),x=read();ll ans=0;fo(i,1,n) a[i]=read(),cnt[i]=0,ans+=a[i];fo(i,1,n){int t=a[i];while(t%x==0){t/=x;cnt[i]++;}}int flag=1;while(flag){fo(i,1,n){if(cnt[i]) cnt[i]--,ans+=a[i];else{flag=0;break;}}}printf("%lld\n",ans);//puts("");
}
int main(){int T=read();while(T--){work();}return 0;
}

CF1471C

假设有 xxx 人直接拿钱,我们选择让 kkk 最小的那 xxx 个人来拿钱肯定是最优的,因为这样能使得剩下的 n−xn-xn−x 个人选择的余地最大,并且代价最小。把 kkk 排序后对 ckic_{k_{i}}cki​​ 做前缀和。这就转化为了在两个递增数组上依次取一段长为 xxx 的前缀和一段长为 m−xm-xm−x 的后缀使得和最小,这显然是一个关于 xxx 的单谷函数,直接无脑三分就能解决。

代码如下:

/*_/      _/    _/_/_/      _/_/_/    _/_/_/_/_/    _/_/_/    _/_/_/_/    _/      _/  _/      _/  _/      _/
_/      _/  _/      _/  _/      _/      _/      _/      _/  _/      _/  _/      _/   _/    _/    _/    _/
_/      _/  _/      _/  _/              _/      _/      _/  _/      _/  _/      _/    _/  _/      _/  _/
_/      _/  _/_/_/_/_/  _/              _/      _/      _/  _/_/_/_/    _/  _/  _/      _/         _/_/_/  _/    _/          _/              _/      _/      _/  _/  _/      _/  _/  _/      _/        _/  _/_/_/     _/      _/  _/      _/      _/      _/      _/  _/    _/     _/_/_/_/       _/       _/    _/_/        _/_/_/      _/_/_/        _/        _/_/_/    _/      _/    _/  _/        _/      _/      _/*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define fo(i,x,y) for(register int i=x;i<=y;++i)
#define go(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;inline int read(){int x=0,fh=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-') fh=-1;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*fh;
}const int N=3e5+5;
int k[N],c[N];
ll S1[N],S2[N];void work(){int n=read(),m=read();ll ans=1e18;fo(i,1,n) k[i]=read();//n个顾客 fo(i,1,m) c[i]=read(),S2[i]=S2[i-1]+c[i];//m件礼品sort(k+1,k+1+n);fo(i,1,n) S1[i]=S1[i-1]+c[k[i]];int L=max(0,n-m),R=n,mid1,mid2;while(R-L>5){mid1=L+(R-L)/3,mid2=R-(R-L)/3;ll v1=S1[mid1]+S2[n-mid1],v2=S1[mid2]+S2[n-mid2];if(v1<=v2) R=mid2;else L=mid1;}fo(i,L,R) ans=min(ans,S1[i]+S2[n-i]);printf("%lld\n",ans);//puts("");
}
int main(){int T=read();while(T--){work();}return 0;
}

CF1471D

思维题。

看到 gcd 和 lcm 首先想到分解质因数。令 a=∏i=1∞piei,b=∏i=1∞piei′a=\prod_{i=1}^{\infin}p_{i}^{e_{i}},b=\prod_{i=1}^{\infin}p_{i}^{e'_{i}}a=∏i=1∞​piei​​,b=∏i=1∞​piei′​​(pip_{i}pi​ 为第 iii 个质数)。则 lcm(a,b)=∏i=1∞pimax⁡(ei,ei′),gcd⁡(a,b)=∏i=1∞pimin⁡(ei,ei′)lcm(a,b)=\prod_{i=1}^{\infin}p_{i}^{\max(e_{i},e'_{i})},\gcd(a,b)=\prod_{i=1}^{\infin}p_{i}^{\min(e_{i},e'_{i})}lcm(a,b)=∏i=1∞​pimax(ei​,ei′​)​,gcd(a,b)=∏i=1∞​pimin(ei​,ei′​)​。令 t=lcm(a,b)gcd(a,b)t=\frac{lcm(a,b)}{gcd(a,b)}t=gcd(a,b)lcm(a,b)​,则t=∏i=1∞pimax⁡(ei,ei′)−min⁡(ei,ei′)t=\prod_{i=1}^{\infin}p_{i}^{\max(e_{i},e'_{i})-\min(e_{i},e'_{i})}t=∏i=1∞​pimax(ei​,ei′​)−min(ei​,ei′​)​。因此 ttt 为完全平方数当且仅当 ∀i∈N+,2∣(max⁡(ei,ei′)−min⁡(ei,ei′))\forall i\in \mathbb{N^{+}},2|(\max(e_{i},e'_{i})-\min(e_{i},e'_{i}))∀i∈N+,2∣(max(ei​,ei′​)−min(ei​,ei′​))。也就是 eie_{i}ei​ 与 ei′e'_{i}ei′​ 奇偶性相同。因此 aaa 和 bbb 是否相邻就只与 eie_{i}ei​ 和 ei′e'_{i}ei′​ 的奇偶性有关了,我们把奇数看做 111,偶数看做 000,每个数就可以用一个 010101 串来表示,而两个数相邻当且仅当它们的 010101 串相同。

这也就是说,每次变化都会将数组中所有 010101 串相同的元素合并在一起(其实就是把这些 010101 串加起来)。如果参与合并的元素个数为偶,那么合并过后每个 eie_{i}ei​ 都会变为 000,即一个全 000 串。如果参与合并的元素个数为奇,那么合并之后每个元素的 010101 串并不会发生改变。这意味着数组在变化过一次后,出现的全 000 串从此始终是全 000 串,非全 000 串从此也不会再发生改变,所以答案最多只有两种: w=0w=0w=0 时,和 w=1w=1w=1 时,直接套哈希模拟就行,由于 010101 串的哈希值只与 111 的位置有关,因此我们可以把所有 111 的位置拎出来做哈希。时间复杂度为 O(nlog⁡n+nmax⁡ai)O(n\log n+n\sqrt {\max a_{i})}O(nlogn+nmaxai​)​。

代码如下:

/*_/      _/    _/_/_/      _/_/_/    _/_/_/_/_/    _/_/_/    _/_/_/_/    _/      _/  _/      _/  _/      _/
_/      _/  _/      _/  _/      _/      _/      _/      _/  _/      _/  _/      _/   _/    _/    _/    _/
_/      _/  _/      _/  _/              _/      _/      _/  _/      _/  _/      _/    _/  _/      _/  _/
_/      _/  _/_/_/_/_/  _/              _/      _/      _/  _/_/_/_/    _/  _/  _/      _/         _/_/_/  _/    _/          _/              _/      _/      _/  _/  _/      _/  _/  _/      _/        _/  _/_/_/     _/      _/  _/      _/      _/      _/      _/  _/    _/     _/_/_/_/       _/       _/    _/_/        _/_/_/      _/_/_/        _/        _/_/_/    _/      _/    _/  _/        _/      _/      _/*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define mod1 998244353
#define mod2 19260817
#define base1 19260813
#define base2 300007
#define ll long long
#define fo(i,x,y) for(register int i=x;i<=y;++i)
#define go(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;inline int read(){int x=0,fh=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-') fh=-1;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*fh;
}const int N=1e6+5;
int np[N],p[N],top,rk[N];void xxs(){fo(i,2,N-1){if(!np[i]) p[++top]=i,rk[i]=top;fo(j,1,top){int t=i*p[j];if(t>=N) break;np[t]=1;if(i%p[j]==0) break;}}
}int a[N];struct Ha{int v1,v2;bool operator<(const Ha &x){if(v1!=x.v1) return v1<x.v1;return v2<x.v2;}bool operator==(const Ha &x){return v1==x.v1&&v2==x.v2;}
}hx[N];void work(){int n=read();fo(i,1,n) a[i]=read();fo(i,1,n){hx[i].v1=hx[i].v2=0;int t=a[i];//printf("%d:\n",t);fo(j,1,top){if(p[j]*p[j]>t) break;bool cnt=0;while(t%p[j]==0){t/=p[j];cnt^=1;}//printf("%d %d\n",p[j],cnt);if(cnt) hx[i].v1=(1ll*hx[i].v1*base1+j)%mod1,hx[i].v2=(1ll*hx[i].v2*base2+j)%mod2;}if(t>1) hx[i].v1=(1ll*hx[i].v1*base1+rk[t])%mod1,hx[i].v2=(1ll*hx[i].v2*base2+rk[t])%mod2;//printf("v1=%d v2=%d\n",hx[i].v1,hx[i].v2);}sort(hx+1,hx+1+n);int ans0=0,ans1=0,cnt=0;fo(i,1,n){int pos=i;while(pos<=n&&hx[pos]==hx[i]) ++pos;int len=pos-i;//printf("%d:%d %d %d %d\n",i,hx[i].v1,hx[i].v2,pos,len);ans0=max(ans0,len);ans1=max(ans1,len);if(len%2==0||hx[i].v1+hx[i].v2==0) cnt+=len;i=pos-1;}ans1=max(ans1,cnt);int q=read();while(q--){ll w;scanf("%lld",&w);if(w==0) printf("%d\n",ans0);else printf("%d\n",ans1);}//puts("");
}int main(){xxs();int T=read();while(T--){work();}return 0;
}

CF1471(Round 694 div2) 题解相关推荐

  1. CF1467(Round 695 div2)题解

    CF1467A 显然: nnn 为 111 时答案为 999 nnn 为 222 时答案为 989898 nnn 为 333 时答案为 989989989 当 n>3n>3n>3 时 ...

  2. Codeforces Round #694 (Div. 1 + Div2)(A ~ H,8题全,超高质量题解)【每日亿题】2021/2/1、2/2

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 [每日亿题]Codeforces Round #694 (Div. 1 + Div2)(A ~ ...

  3. Codeforces Round #694 Div. 2

    Codeforces Round #694 Div. 2 CodeForces 1471A Strange Partition CodeForces 1471B Strange List CodeFo ...

  4. (6/6) Codeforces Round #694 (Div. 2)

    (6/6) Codeforces Round #694 (Div. 2) A. Strange Partition 题意: 给一个数组,数组中的所有元素可以任意合并,求数组的每个元素除以x上去整的和, ...

  5. “玲珑杯”ACM比赛 Round #18 ABC题解

    A -- 计算几何你瞎暴力 Time Limit:5s Memory Limit:256MByte Submissions:1597Solved:301 DESCRIPTION 今天HHHH考完了期末 ...

  6. Codeforces Round #694 (Div. 1) 部分简要题解

    A - Strange Birthday Party 越大的人应该获得更小价值的礼物. 证明:有两个人,其中,有两个礼物价值分别是,其中.当分别获得礼物,付出的代价是.当分别获得礼物,付出的代价是. ...

  7. CF Round #679 div2赛后总结

    前言 好不容易遇到一次简单的div2,竟然才A了三题,可恶的第4题,死活调不出来QAQ. 比赛地址 A 题意:给你TTT组数据,每组数据nnn个整数(nnn是偶数),分别为a1,a2,...,ana_ ...

  8. Codeforces Round#713 A-E题解

    Codeforces Round 713 经典暴力模拟掉分场 本场链接: https://codeforces.com/contest/1512 个人博客の极致色彩简洁版题解: http://www. ...

  9. Codeforces Global Round 9 A-D题解

    文章目录 A - Sign Flipping B - Neighbor Grid C - Element Extermination D - Replace by MEX A - Sign Flipp ...

最新文章

  1. 购华为第1书,写书评赢大奖
  2. 【机器视觉】 repeat算子
  3. js中的==与===的区别
  4. 2022年Java项目课程目录
  5. 12月10日站立会议
  6. fastadmin项目实战踩坑
  7. 如何一键重装Win7系统 便捷重装Win7系统教程
  8. 从传课网论公司是否要卖给资方控股
  9. sci的figure怎么做_论文攻略丨SCI论文插图怎么做?有这一篇文章就够了
  10. 神经网络Neural Networks概述
  11. 新员工如何快速融入新的工作环境
  12. Qt动态图表更新实现
  13. 数据分析python面试题_10道Python常见面试题
  14. android google定位和地图
  15. 爬虫漫游指南:HTTP/2 网站爬取
  16. python保存变量到本地,下次读取。
  17. AARRR模型——揭开应用推广运营背后的秘密
  18. html实现纸张撕边效果,PS图片处理教程:PS撕边效果,脸部撕纸效果
  19. 动脑学院-网络请求框架
  20. 【成长必备】我为什么推荐你写博客?愿你多年以后成为你想成为的样子。

热门文章

  1. replaceAll() 方法
  2. 《美团机器学习实践》读后感和一点思考
  3. 杨飞致工管院的朋友们及湖南大学教研同仁的一封信[转]
  4. JS 中字符和 ASCII码转换函数
  5. Markdown语法005:分割线
  6. 多个时间序列之间的DTW
  7. 前端开发:Vue3.0提示警告Avoid app logic that relies on enumerating keys on a component instance… 的解决方法
  8. 【大三上又要结束了——贩卖焦虑篇】
  9. 简单快速的“0x800c0006 安装失败 .NET framework 等旧版本软件安装失败”的解决方法
  10. 怎么做动图?轻松在线制作gif动图的技巧