Warning: session_start(): open(/tmp/sess_368dc7668e2833d5d608b3e519840b5c, O_RDWR) failed: No space left on device (28) in /data/wiki/inc/init.php on line 239

Warning: session_start(): Failed to read session data: files (path: ) in /data/wiki/inc/init.php on line 239

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/auth.php on line 430

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/actions.php on line 38

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/lib/tpl/dokuwiki/main.php on line 12
2020-2021:teams:legal_string:jxm2001:数论_1 [CVBB ACM Team]

用户工具

站点工具


2020-2021:teams:legal_string:jxm2001:数论_1

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
2020-2021:teams:legal_string:jxm2001:数论_1 [2020/07/02 19:32]
jxm2001
2020-2021:teams:legal_string:jxm2001:数论_1 [2020/07/27 22:56] (当前版本)
jxm2001 ↷ 页面2020-2021:teams:legal_string:数论_1被移动至2020-2021:teams:legal_string:jxm2001:数论_1
行 39: 行 39:
 ==== 算法简介 ==== ==== 算法简介 ====
  
-数论分块用于解决形如 $\sum_{i=1}^n \lfloor \frac ni\rfloor$ 的问题,时间复杂度 $O(\sqrt n)$。+数论分块用于解决形如 $\sum_{i=1}^n ​a_if(\lfloor \frac ni\rfloor)$ 的问题,通过预处理 $a_i$ 前缀和,可以把时间复杂度降到  ​$O(\sqrt n)$。
  
 ==== 算法思想 ==== ==== 算法思想 ====
行 77: 行 77:
 <hidden 查看代码>​ <hidden 查看代码>​
 <code cpp> <code cpp>
-#include <​cstdio>​ +LL pre_s(int k){return 1LL*k*(k+1)/2;} 
-#include <​iostream>​ +LL cal(int i,int n){ 
-#include <​vector>​ + LL ans=0; 
-#include <​algorithm>​ + int lef=1,rig=0
-#include <​cstring>​ + while(lef<=i){ 
-#include <​cctype>​ + rig=min(i,n/(n/lef)); 
-#include <​queue>​ + ans+=(pre_s(rig)-pre_s(lef-1))*(n/lef); 
-#include <​cmath>​ + lef=rig+1; 
-#define _for(i,a,b) for(int i=(a);i<(b);++i) +
-#define _rep(i,a,b) for(int i=(a);​i<​=(b);​++i) + return ​ans;
-#define mem(a,b) memset((a),​(b),​sizeof(a)) +
-using namespace std; +
-typedef long long LL; +
-inline ​int read_int(){ +
- int t=0;bool sign=false;char c=getchar()+
- while(!isdigit(c)){sign|=c=='​-';​c=getchar();} +
- while(isdigit(c)){t=(t<<1)+(t<<​3)+(c&15);c=getchar();} +
- return ​sign?-t:t;+
 } }
-inline LL read_LL(){ +int main() 
- LL t=0;bool sign=false;​char c=getchar()+
- while(!isdigit(c)){sign|=c=='​-';​c=getchar();} + LL n=read_int(),k=read_int(); 
- while(isdigit(c)){t=(t<<1)+(t<<​3)+(c&15);c=getchar();​} + enter(n*k-cal(min(n,k),k)); 
- return ​sign?-t:t;+ return ​0;
 } }
-inline void write(LL x){ +</​code>​ 
- register char c[21],len=0; +</​hidden>​ 
- if(!x)return putchar('​0'​),void(); + 
- if(x<0)x=-x,​putchar('​-')+==== 算法练习 ==== 
- while(x)c[++len]=x%10,x/=10+ 
- while(len)putchar(c[len--]+48);+[[https://​www.luogu.com.cn/​problem/​P2260|洛谷p2260]] 
 + 
 +=== 题意 === 
 + 
 +求 \begin{equation}\sum_{i=1}^n\sum_{j=1}^m [i\ne j](n\ mod\ i)\ast (m\ mod\ j)\pmod ​{19940417}\end{equation} 
 + 
 +=== 题解 === 
 + 
 +不妨设 $n\le m$。 
 + 
 +\begin{equation}\sum_{i=1}^n\sum_{j=1}^m ​[i\ne j](n\ mod\ i)\ast (m\ mod\ j)=\sum_{i=1}^n ​(n\ mod\ i)\ast\sum_{j=1}^m ​(m\ mod\ j)-\sum_{i=1}^n ​(n\ mod\ i)\ast (m\ mod\ i)\end{equation} 
 + 
 +前面两项解法同模板题,主要关注最后一项。 
 + 
 +\begin{equation}\sum_{i=1}^n ​(n\ mod\ i)\ast (m\ mod\ i)=\sum_{i=1}^n n\ast m-n\ast i\ast \lfloor\frac mi\rfloor-m\ast i\ast \lfloor\frac ni\rfloor+i^2\ast\lfloor\frac ni\rfloor\ast\lfloor \frac mi\rfloor\end{equation} 
 + 
 +类似的,也可以用数论分块解决,注意这条式子的最后一项需要同时处理 $n$ 和 $m$ 的分块边界。 
 + 
 +<hidden 查看代码>​ 
 +<code cpp> 
 +const int mod=19940417
 +LL inv6; 
 +LL exgcd(LL a,LL b,LL &tx,LL &ty)
 + if(b==0){ 
 + tx=1,ty=0
 + return a; 
 +
 + LL re=exgcd(b,a%b,ty,tx)
 + ty-=a/b*tx; 
 + return re;
 } }
-inline void space(LL x){write(x),​putchar('​ ');} +LL pre_s_1(int k){return 1LL*k*(k+1)/2%mod;} 
-inline void enter(LL x){write(x),putchar('​\n'​);} +LL s_1(int lef,int rig){return ​(pre_s_1(rig)-pre_s_1(lef-1))%mod;} 
-const int MAXP=3e6+5; +LL pre_s_2(int k){return 1LL*k*(k+1)%mod*(2*k+1)%mod*inv6%mod;​} 
-LL pre_s(int k){ +LL s_2(int lef,int rig){return (pre_s_2(rig)-pre_s_2(lef-1))%mod;​} 
- return 1LL*k*(k+1)/2;+LL cal_1(int i,int n){ 
 + LL ans=0; 
 + int lef=1,​rig=0;​ 
 + while(lef<​=i){ 
 + rig=min(i,​n/​(n/​lef));​ 
 + ans=(ans+s_1(lef,​rig)*(n/​lef)%mod)%mod;​ 
 + lef=rig+1;​ 
 +
 + return ans;
 } }
-LL cal(int n,int k){+LL cal_2(int i,int n,int m){
  LL ans=0;  LL ans=0;
  int lef=1,​rig=0;​  int lef=1,​rig=0;​
- while(lef<​=n){ + while(lef<​=i){ 
- rig=min(n,​k/(k/lef)); + rig=min(i,min(n/(n/lef),m/(m/lef))); 
- ans+=(pre_s(rig)-pre_s(lef-1))*(k/lef);+ ans=(ans+s_2(lef,rig)*(n/lef)%mod*(m/lef)%mod)%mod;
  lef=rig+1;​  lef=rig+1;​
  }  }
行 127: 行 156:
 int main() int main()
 { {
- LL n=read_int(),​k=read_int();​ + LL n=read_int(),​m=read_int(),ans,t
- enter(n*k-cal(min(n,k),k));+ if(n>​m) 
 + swap(n,​m);​ 
 + exgcd(6,​mod,​inv6,​t);​ 
 + inv6%=mod;​ 
 + ans=(n*n-cal_1(n,​n))%mod*((m*m-cal_1(m,​m))%mod)%mod;​ 
 + ans=(ans-n*n%mod*m%mod)%mod;​ 
 + ans=(ans+n*cal_1(n,m)%mod)%mod;​ 
 + ans=(ans+m*cal_1(n,n)%mod)%mod;​ 
 + ans=(ans-cal_2(n,​n,​m))%mod;​ 
 + ans=(ans+mod)%mod;​ 
 + enter(ans);
  return 0;  return 0;
 } }
 </​code>​ </​code>​
 </​hidden>​ </​hidden>​
2020-2021/teams/legal_string/jxm2001/数论_1.1593689543.txt.gz · 最后更改: 2020/07/02 19:32 由 jxm2001