首页 > 其他分享 >CF1601F Two Sorts 题解--zhengjun

CF1601F Two Sorts 题解--zhengjun

时间:2023-07-10 14:44:56浏览次数:47  
标签:lfloor frac -- 题解 ll Two rfloor int rk

link

这里提供一种不用 meet in middle 的方法,速度比较可观。

发现性质

开始简单的推一下式子。

\(\sum (i-a_i)\bmod p=\sum (rk_i-i-p\times\lfloor\frac{rk_i-i}{p}\rfloor)=-p\times \sum\lfloor\frac{rk_i-i}{p}\rfloor,p=998244353\)

于是,只需求出 \(\sum\lfloor\frac{rk_i-i}{p}\rfloor\) 即可。

由于 \(p\) 达到了 \(10^9\) 级别,而且 \(rk_i-i\in [-n,n]\)。

所以 \(\lfloor\frac{rk_i-i}{p}\rfloor\) 在 \(O(\frac{n}{p})\) 级别。

转化问题

考虑枚举 \(k=\lfloor\frac{rk_i-i}{p}\rfloor\),计算符合条件的 \(i\) 的个数。

对于 \(i\) 的限制即为:\(k\times p \le rk_i-i < (k+1)\times p\)。

直接差分掉,问题转化为求出 \(rk_i-i \le lim\) 的 \(i\) 的个数。

再发现性质

对于位数相同的数 \(i-1,i\),发现字典序大小即为数值本身的大小。

所以 $rk_{i-1} +1 \le rk_{i}\iff rk_{i-1}-(i-1)\le rk_i -i $。

发现 \(rk_i-i\) 在相同位数的时候是递增的。

最后

于是,我们可以先枚举 \(i\) 的位数 \(len\)。

然后二分出该位数下满足 \(rk_i-i < lim\) 的最大的 \(i\) 即可。

还留下来最后一个问题,如何求出 \(rk_i\)?

计算 \(str(j)<str(i)\) 的个数,可以枚举 \(j\) 的位数,直接计算个数即可。

时间复杂度

总结步骤:

  • 枚举 \(k=\lfloor\frac{rk_i-i}{p}\rfloor,O(\frac{n}{p})\)

  • 枚举 \(i\) 的位数,\(O(\log n)\)

  • 二分 \(i\),\(O(\log n)\)

  • 计算 \(rk_i\),即枚举 \(j\) 的位数,\(O(\log n)\)

总时间复杂度:\(O(\frac{n}{p}\log^3 n)\),常数很小,跑得飞快

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
using ll=long long;
const int N=20,p=998244353,mod=1e9+7;
char num[N];
int len;
ll n,pw[N];
int k,a[N];
ll getrk(ll x){
	k=0;
	for(ll y=x;y;y/=10)a[++k]=y%10;
	for(int i=k+1;i<=len;i++)a[i]=0;
	reverse(a+1,a+1+k);
	ll now=0,ans=0;
	for(int i=1;i<k;i++){
		now=now*10+a[i];
		ans+=now-pw[i-1]+1;
	}
	for(int i=k;i<len;i++){
		now=now*10+a[i];
		ans+=now-pw[i-1];
	}
	now=now*10+a[len];
	if(now<=n)ans+=now-pw[len-1];
	else ans+=n-pw[len-1]+1;
//	fprintf(stderr,"getrk %lld %lld\n",x,ans+1);
	return ans+1;
}
ll query(ll lim){
	ll ans=0;
	for(int i=1;i<=len;i++){
		ll l=pw[i-1]-1,r=min(pw[i],n+1),mid;
		for(;l+1<r;){
			mid=(l+r)>>1;
			if(getrk(mid)-mid<lim)l=mid;
			else r=mid;
		}
		ans+=l-pw[i-1]+1;
	}
//	cerr<<"query "<<lim<<' '<<ans<<endl;
	return ans;
}
signed main(){
	scanf("%s",num+1),len=strlen(num+1);
	for(int i=1;i<=len;i++)n=n*10+num[i]-'0';
	for(int i=pw[0]=1;i<=len;i++)pw[i]=pw[i-1]*10;
	ll las=0,ans=0;
	for(ll k=-n/p-1;k*p<=n;k++){
		ll cnt=query((k+1)*p);
		ans-=k*(cnt-las),las=cnt;
	}
	cout<<(ans%mod*p%mod+mod)%mod;
	return 0;
}

标签:lfloor,frac,--,题解,ll,Two,rfloor,int,rk
From: https://www.cnblogs.com/A-zjzj/p/17541141.html

相关文章

  • Python的日志
    Python的日志,看上去啰啰嗦嗦的。请大神写了个通俗易懂简单方便通用的日志:importlogging#配置日志记录级别和输出方式logging.basicConfig(level=logging.DEBUG,filename='mylog.log',filemode='w',format='%(asctime)s-%(levelname)s-%(message)s')deflog_exceptio......
  • 西门子免授权CNC数控系统数据采集c#、C、python都支持,可支持再各种操作系统上运行,无须
    西门子数控系统数据采集方案(无需OPC授权方案)西门子数控系统4.5版本及以上集成了工业协议OPCUA,用户可通过OPCUA协议进行设备的数据采集,但是需要西门子授权,而且仅支持828d,828dsl,840dsl本协议可通过原生TCP数据包和数控系统进行通讯,支持各种类型开发语言和操作平台。  西门......
  • 第一节 线性数据结构 STL
    vector容器迭代器vector<int>v{1,0,0,8,6};for(vector<int>::interatorit=v.begin();it!=v.end();it++)cout<<*it<<"";函数push_back(x);//添加元素pop_back();//删除尾元素size();//查询vector长度insert(i......
  • python过滤器filter()及lambda表达式的应用
    一、filter()方法介绍:filter()是Python内置的一个函数,用于根据指定的条件对可迭代对象进行筛选,返回符合条件的元素。filter()函数的语法如下:filter(function,iterable)其中function是一个函数或可调用对象,表示用于判断每个元素是否符合条件的函数。iterable则是一个可......
  • nerdctl 构建镜像
    1、安装buildkit客户端,buildkit服务下载地址:wgethttps://github.com/moby/buildkit/releases/download/v0.11.6/buildkit-v0.11.6.linux-amd64.tar.gz解压复制到/usr/bintar-xvfbuildkit-v0.11.6.linux-amd64.tar.gzcp-rp/bin/{buildctl,buildkitd}/usr/bin/2、安......
  • 数学建模赛题类型
    评价类指标定权:主观经验,客观公式评价方法数据量小,评价指标少——————层次分析法数据量较小,样本数据具有时间序列特性——————灰色关联分析法时间序列时间序列是将某个统计量按照时间发生的先后顺序,按照其统计的值排列成的数列。时间序列分析通过已经发生的序列数......
  • 视频直播系统源码,uniapp滚动加载 下拉刷新
    视频直播系统源码,uniapp滚动加载下拉刷新滚动加载滚动加载指的是当用户滑动页面到底部时,自动加载更多数据。在uniapp中,我们可以通过监onReachBottom来实现滚动加载。 onReachBottom页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。onReachBottom使用注意......
  • Atcoder ARC164B Switching Travel
    称\(c_u\not=c_v\)的边\((u,v)\)为普通边,\(c_u=c_v\)的边\((u,v)\)为特殊边。能发现若满足条件则这个环应该是由一条特殊边和若干条普通便组成的(从特殊边的一个顶点出发一直经过普通边,最后走到特殊边的另一个顶点再走回来)。于是若这个特殊边的两个顶点能只通过普通......
  • 注塑机数据采集(海天、住友、发那科、力劲、伊之密、恩格尔、泰瑞、佳明、双马、宁波通
    注塑机企业比较关注机实时状态、工艺参数(温度压力)、机器生产效率、设备能耗,运行时间、设备温度压力参数、以及各类工艺参数先上采集图,下面将技术拆解通讯模式(非应答模式)  文章以海天注塑机为列海天系列主要用弘讯控制器为主,弘讯TECH系列(如580、1s、2s、530)、弘讯AK系列......
  • java List去重的代码
    一、HashSet去重我们知道 HashSet 天生具备“去重”的特性,那我们只需要将List集合转换成HashSet集合就可以了,实现代码如下:publicclassListDistinctExample{publicstaticvoidmain(String[]args){List<Integer>list=newArrayList<Integer>(){{......