卡完常后来造福一下人类

如何从4.80s卡到920ms.jpg

本题解的复杂度为 \(O(\frac {n^{3/4}} {\log n})\),然而标算是 \(O(\frac {n^{2/3}} {\log^{1/3} n})\) 的。。。

有时间尝试卡一下标算,但是看样子好像已经卡过一些了,不知道能不能比我这个代码快(

首先亮出经典 DP:

\[f(n,id)=f(n,id-1)-p_{id}^k \times (f(\frac n {p_{id}},id-1)-f(p_{id},id-1))
\]

然后你写完之后稍微卡一下,再吸个氧就能得到4.80s的代码了。

稍微卡一下指把DP的部分中的int和ll分开,并且线性筛进行了一些神奇的优化(

然后我们开始卡。

首先加了一个FastMod,速度变成了2.57s

然后众所周知的是,实数除法比整数除法要快,变成了1.31s。

然后我们知道线性筛的原理是 用自身最小的质因子筛掉自己,那么我们没有必要用除法,将其记录下来即可,1.13s。

然后我们将减法优化改成暴力取模,发现变成了1.06s。

然后由于我的DP过程中边界是这样判的:

for(;j<=tot&&pri[i]<=(m1=w[j]*invp[i]);++j)

我们发现只需要将pri[top+1]改为INF就能够避免掉前面的那个j<=tot,这次卡进了1s,970ms。

然后由于我们DP时每次都计算了一遍sum[i-1]+p,我们就新开了一个变量s将其存下来,920ms。

upd:把f中的n故技重施能卡到915ms。

不知道还能不能卡/youl

upd:把前面的一些“优化”删掉之后跑了885ms。

#include<cstdio>
#include<cmath>
typedef long long ll;
typedef __uint128_t L;
typedef unsigned long long ull;
const ll M=2e5+5;
int k,p,a[15],ifac[15],sl[15],sr[15];
int S,id1[M],id2[M];ll tot,g[M<<1];ll n,w[M<<1];
int top,F[17985],pri[17985],sum[17985],pos[M];bool zhi[M];
double invp[17985];
struct FastMod{
ull b,m;
FastMod(ull b):b(b),m(ull((L(1)<<64)/b)){}
friend inline ull operator%(const ull&a,const FastMod&mod){
ull q=(L(mod.m)*a)>>64;
ull r=a-q*mod.b;
return r>=mod.b?r-mod.b:r;
}
}mod(2);
inline int pow(int a,int b){
register int ans=1;
for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;
return ans;
}
inline void init(){
register int i;k+=2;a[1]=sl[0]=sr[k+1]=ifac[0]=ifac[1]=1;
for(i=2;i<=k;++i)a[i]=(a[i-1]+pow(i,k-2))%mod,ifac[i]=1ll*(p-p/i)*ifac[p%i]%mod;
for(i=2;i<=k;++i)ifac[i]=1ll*ifac[i-1]*ifac[i]%mod;
for(i=1;i<=k;++i)a[i]=1ll*ifac[i-1]*(k-i&1?p-ifac[k-i]:ifac[k-i])%mod*a[i]%mod;
}
inline int f(const int&n){
register int i,N=n+p;register ull ans=0;
for(i=1;i<=k;++i)sl[i]=1ll*sl[i-1]*(N-i)%mod;
for(i=k;i>=1;--i)sr[i]=1ll*sr[i+1]*(N-i)%mod;
for(i=1;i<=k;++i)ans+=1ll*sr[i+1]*sl[i-1]%mod*a[i];
return ans%mod;
}
inline void sieve(const int&n){
register int i=6,j,x,m;top=2;
F[1]=pow(pri[1]=2,k);F[2]=pow(pri[2]=3,k);
sum[1]=F[1];sum[2]=F[1]+F[2];
invp[1]=1./2*(1+1e-15);invp[2]=1./3*(1+1e-15);
do{
if(!zhi[m=i-1]&&i-1<=n){
pri[++top]=m;sum[top]=(sum[top-1]+(F[top]=pow(m,k)))%mod;
invp[top]=1./m*(1+1e-15);
}
for(j=3;j<=top&&(x=m*pri[j])<=n;++j){
zhi[x]=true;if((pos[x]=j)==pos[m])break;
}
if(!zhi[m=i+1]&&i+1<=n){
pri[++top]=m;sum[top]=(sum[top-1]+(F[top]=pow(m,k)))%mod;
invp[top]=1./m*(1+1e-15);
}
for(j=3;j<=top&&(x=m*pri[j])<=n;++j){
zhi[x]=true;if((pos[x]=j)==pos[m])break;
}
}while((i+=6)-1<=n);pri[++top]=p;invp[top]=0;
}
void Solve(const ll&n){
const ll&n9=n/1e9;
register int i,j,k,s;register ll m,L=1,R;
for(;L<=n;L=R+1,--g[tot]){
R=n/(m=w[++tot]=1.*n/L);g[(m<=S?id1[m]:id2[R])=tot]=f(m%mod);
}
for(i=1;i<=top;++i){
s=sum[i-1]+p;
for(j=1;pri[i]<=(m=w[j]*invp[i]);++j){
g[j]+=1ll*F[i]*(s-g[m<=S?id1[m]:id2[int(1.*n/m)]])%mod;
if(g[j]>=p)g[j]-=p;
}
}
}
signed main(){
register int i=1;register ull ans=0;
scanf("%lld%d%d",&n,&k,&p);mod=FastMod(p);
sieve(S=sqrt(n));init();Solve(n);
for(register ll m;i<=S;++i){
m=1.*n/i;
ans+=1ll*i*i%mod*g[m<=S?id1[m]:id2[ll(1.*n/m)]]%mod;
if(ans>=p)ans-=p;
}
printf("%d",ans);
}

LGP5493题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. 抓包神器 tcpdump 使用介绍 (转)

    tcpdump 命令使用简介 简单介绍 tcpdump 是一款强大的网络抓包工具,运行在 linux 平台上.熟悉 tcpdump 的使用能够帮助你分析.调试网络数据. 要想使用很好地掌握 tcpdu ...

  2. Python多线程并发的误区

    由于项目要做一个并发测试,由于断言的东西较多,决定手写脚本.于是用python写了脚本: def test_method(thread_no): print("%s===test_metho ...

  3. Ansible自动化运维工具及其常用模块

    Ansible自动化运维工具及其常用模块 目录 Ansible自动化运维工具及其常用模块 一.Ansible简介 1. Ansible概述 2. Ansible作用 3. Ansible的工作模块 4 ...

  4. Java多线程之读写锁机制

    Java多线程中有很多的锁机制,他们都有各自的应用场景,例如今天我说的这种锁机制:读写锁 读写锁,见名知意,主要可以进行两种操作,读和写操作,他们之间结合使用起来又是各不相同的.比如多个线程之间可以同 ...

  5. vc++调试总结

    .在debug->windows下,有以下调试窗口 1)Breakpoints管理断点信息 可以新建条件断点,函数断点,以及特定地址改变断点(用于检测数据发生改变时机点) 在断点处,可以进入汇编 ...

  6. SQL注入蠕虫分析//未完待续

    蠕虫代码: DECLARE @S VARCHAR(4000);SET @S=CAST(0x4445434C415245204054205641524348415228323535292C4043205 ...

  7. 我来教你如何用Docker部署最近火爆的人生重开模拟器

    文章目录 获取项目源码包 Dockerfile 构建docker镜像 启动docerk容器 访问liferestart 如果人生可以重来... <可惜没如果> github项目地址:htt ...

  8. 为什么我建议在复杂但是性能关键的表上所有查询都加上 force index

    最近,又遇到了慢 SQL,简单的看了下,又是因为 MySQL 本身优化器还有查询计划估计不准的问题.SQL 如下: select * from t_pay_record WHERE (( user_i ...

  9. sql注入代码分析及预防

    sql注入的原因,表面上说是因为 拼接字符串,构成sql语句,没有使用 sql语句预编译,绑定变量.但是更深层次的原因是,将用户输入的字符串,当成了 "sql语句" 来执行. 1. ...

  10. [题解]第十一届北航程序设计竞赛预赛——A.模式

    题目描述 输入一个学号,判断是计算机系or软件学院or其他院系. 解题思路 水题,直接判断or除以10000都可以.不废话,直接上代码. 1 #include <iostream> 2 # ...