题意

给定两个整数 \(n,m\),求

\[\sum\limits_{i=1}^{n}\frac{1}{\prod\limits_{j=i}^{i+m-1}j}
\]

\(\texttt{Data Range:}1\leq n+m\leq 500\)

题解

小学奥数,裂项相消。

比如说有如下例子:

\[\frac{1}{1\times2\times3}=\frac{1}{2}\left(\frac{1}{1\times2}-\frac{1}{2\times 3}\right)
\]

考虑以这个作为范例来 generalize 一下

\[\frac{1}{\prod\limits_{j=i}^{i+m-1}j}=\frac{1}{m-1}\left(\frac{1}{\prod\limits_{j=i}^{i+m-2}j}-\frac{1}{\prod\limits_{j=i+1}^{i+m-1}j}\right)
\]

然后求和就好了,注意到右边是叠缩求和,直接用最后一项减去第一项即可。

\[\sum\limits_{i=1}^{n}\frac{1}{\prod\limits_{j=i}^{i+m-1}j}=\frac{1}{m-1}\sum\limits_{i=1}^{n}\left(\frac{1}{\prod\limits_{j=i}^{i+m-2}j}-\frac{1}{\prod\limits_{j=i+1}^{i+m-1}j}\right)=\frac{1}{m-1}\left(\frac{1}{\prod\limits_{j=1}^{m-1}j}-\frac{1}{\prod\limits_{j=n+1}^{n+m-1}j}\right)
\]

接下来考虑如何不写高精除高精来通过这个题。

显然括号内的东西通分是可以靠分子分母的质因数分解形式的。

于是只要先算出括号内分子分母的质因数分解形式,再用高精乘算出实际分子,减去 \(1\) 之后再质因数分解。最后分子分母抵掉就好了。

所以这个时候只需要考虑高精除低精和高精模低精两个操作就好了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51,BASE=1000000000;
const li BASE2=(li)BASE*BASE;
struct BigInt{
vector<ll>v;
ll neg;
BigInt();
BigInt(const string &x);
BigInt(const char *x);
BigInt(ll x);
BigInt(li x);
BigInt(const BigInt &x);
inline void setup();
inline void setupStr(const char *str);
inline BigInt& reduce();
inline ll isZero()const;
inline string toString()const;
inline void op()const;
inline BigInt &operator =(const string &x);
inline BigInt &operator =(const char *x);
inline BigInt &operator =(ll x);
inline BigInt &operator =(li x);
inline BigInt &operator =(const BigInt &x);
inline ll compareAbs(const BigInt &x)const;
};
ll n,m,c;
BigInt f,g;
ll fn[MAXN],fd[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline void BigInt::setup()
{
neg=0,v.clear(),v.push_back(0);
}
inline void BigInt::setupStr(const char *str)
{
ll len;
char token[10];
setup(),len=strlen(str),*str=='-'?neg=1,++str,--len:1,token[9]=0;
if(!len||(len==1&&*str=='0'))
{
return (void)(neg=0);
}
v.clear();
for(register int i=1;i*9<=len;i++)
{
memcpy(token,str+(len-i*9),9),v.push_back((ll)(strtol(token,NULL,10)));
}
if(len%9)
{
memcpy(token,str,len%9),token[len%9]=0;
v.push_back((ll)(strtol(token,NULL,10)));
}
reduce();
}
inline ll BigInt::isZero()const
{
return v.size()==1&&!v.back();
}
inline BigInt& BigInt::reduce()
{
while(v.size()>1&&!v.back())
{
v.pop_back();
}
return isZero()?neg=0:1,*this;
}
inline string BigInt::toString()const
{
string res;
char token[10];
ll c=v.size()-1;
neg&&!this->isZero()?res.push_back('-'):(void)1;
for(sprintf(token,"%d",v[c]);res+=token,c--;sprintf(token,"%09d",v[c]));
return res;
}
inline void BigInt::op()const
{
return (void)(cout<<this->toString());
}
BigInt::BigInt()
{
setup();
}
BigInt::BigInt(const string &x)
{
this->setupStr(x.c_str());
}
BigInt::BigInt(const char *x)
{
this->setupStr(x);
}
BigInt::BigInt(ll x)
{
setup(),x<0?(neg=1,x=-x):1,v.back()=x%BASE;
x>=BASE?v.push_back(x/BASE):(void)1;
}
BigInt::BigInt(li x)
{
setup(),x<0?(neg=1,x-=x):1,v.back()=x%BASE;
x>=BASE?v.push_back(x/BASE%BASE):(void)1;
x>=BASE2?v.push_back(x%BASE2):(void)1;
}
BigInt::BigInt(const BigInt &x)
{
neg=x.neg,v=x.v;
}
inline BigInt& BigInt::operator =(const string &x)
{
return this->setupStr(x.c_str()),*this;
}
inline BigInt& BigInt::operator =(const char *x)
{
return this->setupStr(x),*this;
}
inline BigInt& BigInt::operator =(ll x)
{
setup(),x<0?(neg=1,x=-x):1,v.back()=x%BASE;
return x>=BASE?v.push_back(x/BASE):(void)1,*this;
}
inline BigInt& BigInt::operator =(li x)
{
setup(),x<0?(neg=1,x=-x):1,v.back()=x%BASE;
x>=BASE?v.push_back(x/BASE%BASE):(void)1;
return x>=BASE2?v.push_back(x%BASE2):(void)1,*this;
}
inline BigInt& BigInt::operator =(const BigInt &x)
{
neg=x.neg,v=x.v,*this;
}
inline ll BigInt::compareAbs(const BigInt &x)const
{
if(v.size()!=x.v.size())
{
return (v.size()<x.v.size())?-1:1;
}
for(register int i=v.size()-1;i>=0;i--)
{
if(v[i]!=x.v[i])
{
return (v[i]<x.v[i])?-1:1;
}
}
return 0;
}
inline BigInt unsignedAdd(BigInt &x,BigInt &y)
{
BigInt res;
ll mx=max(x.v.size(),y.v.size()),carry=0;
x.v.resize(mx+1),y.v.resize(mx+1),res.v.resize(mx+1);
for(register int i=0;i<=mx;i++)
{
(res.v[i]=x.v[i]+y.v[i]+carry)>=BASE?res.v[i]-=BASE,carry=1:carry=0;
}
return x.reduce(),y.reduce(),res.reduce();
}
inline BigInt unsignedSub(BigInt &x,BigInt &y)
{
BigInt res;
ll mx=max(x.v.size(),y.v.size()),carry=0;
x.v.resize(mx+1),y.v.resize(mx+1),res.v.resize(mx+1);
for(register int i=0;i<=mx;i++)
{
(res.v[i]=x.v[i]-y.v[i]+carry)<0?res.v[i]+=BASE,carry=-1:carry=0;
}
return x.reduce(),y.reduce(),res.reduce();
}
inline BigInt operator +(BigInt x,BigInt y)
{
BigInt res;
res=x.neg==y.neg?unsignedAdd(x,y):unsignedSub(x,y);
return res.neg=x.neg!=y.neg?(x.compareAbs(y)>=0?x.neg:y.neg):x.neg,res;
}
inline BigInt operator +=(BigInt &x,BigInt y)
{
return x=x+y,x;
}
inline BigInt operator -(BigInt x,BigInt y)
{
BigInt res;
res=x.neg==y.neg?unsignedSub(x,y):unsignedAdd(x,y);
return res.neg=x.neg==y.neg?(x.compareAbs(y)>=0?x.neg:y.neg):x.neg,res;
}
inline BigInt operator -=(BigInt &x,BigInt y)
{
return x=x-y,x;
}
inline BigInt operator *(BigInt x,ll u)
{
BigInt res;
ll mx=x.v.size(),carry=0;
x.v.resize(mx+1),res.v.resize(mx+1),res.neg=x.neg,u<0?res.neg^=1,u=-u:1;
for(register int i=0;i<=mx;i++)
{
res.v[i]=((li)x.v[i]*u+carry)%BASE,carry=((li)x.v[i]*u+carry)/BASE;
}
return x.reduce(),res.reduce();
}
inline BigInt operator *(BigInt x,BigInt y)
{
if(x.isZero()||y.isZero())
{
return BigInt();
}
BigInt res;
ll n=x.v.size(),m=y.v.size(),j,k;
li cur=0,carry=0;
res.neg=x.neg^y.neg,res.v.resize(n+m);
for(register int i=0;i<n+m;i++)
{
for(i<m?(j=0,k=i):(j=i-m+1,k=m-1);j<n&&k>=0;j++,k--)
{
cur+=(li)x.v[j]*y.v[k],carry+=cur/BASE,cur%=BASE;
}
res.v[i]=cur,cur=carry%BASE,carry/=BASE;
}
return res.reduce();
}
inline BigInt operator /(BigInt x,ll u)
{
BigInt res;
li cur=0;
res.neg=x.neg,u<0?res.neg^=1,u=-u:1,res.v.resize(x.v.size()+1);
for(register int i=x.v.size()-1;i>=0;i--)
{
cur=cur*BASE+x.v[i],cur-=(li)(res.v[i]=cur/u)*u;
}
return res.reduce();
}
inline li operator %(BigInt x,ll u)
{
li cur=0;
for(register int i=x.v.size()-1;i>=0;i--)
{
cur=cur*BASE+x.v[i],cur-=(li)(cur/u)*u;
}
return cur;
}
inline BigInt qpow(BigInt base,ll exponent)
{
BigInt res=1;
while(exponent)
{
if(exponent&1)
{
res=res*base;
}
base=base*base,exponent>>=1;
}
return res;
}
int main()
{
n=read(),m=read(),f=g=1;
for(register int i=n+1;i<=n+m-1;i++)
{
c=i;
for(register int j=2;j<=sqrt(c);j++)
{
while(c%j==0)
{
fd[j]++,fn[j]++,c/=j;
}
}
c!=1?fd[c]++,fn[c]++:1;
}
for(register int i=1;i<=m-1;i++)
{
c=i;
for(register int j=2;j<=sqrt(c);j++)
{
while(c%j==0)
{
fn[j]--,c/=j;
}
}
c!=1?fn[c]--:1;
}
for(register int i=1;i<=501;i++)
{
f=f*qpow(i,fn[i]),fn[i]=0;
}
f=f-1,fd[m-1]++;
for(register int i=2;i<=501;i++)
{
while(f%i==0)
{
fn[i]++,f=f/i;
}
}
for(register int i=1;i<=501;i++)
{
if(fd[i]>fn[i])
{
g=g*qpow(i,fd[i]-fn[i]);
}
if(fn[i]>fd[i])
{
f=f*qpow(i,fn[i]-fd[i]);
}
}
f.op(),puts(""),g.op();
}

Luogu P1625 求和的更多相关文章

  1. Luogu 2671 求和 NOIP2015T3

    题目链接 题解 20pts $O(n^3)$枚举$x,y,z$,根据题目要求判断 40pts $O(n^2)$枚举$x,z$,需要满足$x,z$奇偶相同 20~40pts的代码我都没有写过...就不贴 ...

  2. luogu 4427 求和

    bjoi 2018 求和 唯一一道可能切的题一个数组还没开long long就成0分了 题目大意: 一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的k次方和,而且每次的k可能是不同的 此处 ...

  3. luogu P1630 求和(枚举暴力)

    题意 题解 可以发现当a=10001时, 和1是等价的. 所以这题就水了. #include<iostream> #include<cstring> #include<c ...

  4. [Luogu] 余数求和

    question: $$\sum_{i=1}^{n} k \bmod i$$$$\sum_{i=1}^{n} k - \lfloor \frac{k}{i} \rfloor i$$$$\sum_{i= ...

  5. [Luogu 2261] CQOI2007 余数求和

    [Luogu 2261] CQOI2007 余数求和 这一定是我迄今为止见过最短小精悍的省选题了,核心代码 \(4\) 行,总代码 \(12\) 行,堪比小凯的疑惑啊. 这题一看暴力很好打,然而 \( ...

  6. BZOJ 4555 Luogu P4091 [HEOI2016/TJOI2016]求和 (第二类斯特林数)

    题目链接 (luogu) https://www.luogu.org/problem/P4091 (bzoj) https://www.lydsy.com/JudgeOnline/problem.ph ...

  7. [Luogu P2261] [CQOI2007]余数求和 (取模计算)

    题面 传送门:https://www.luogu.org/problemnew/show/P2261 Solution 这题显然有一个O(n)的直接计算法,60分到手. 接下来我们就可以拿出草稿纸推一 ...

  8. 【Bzoj4555】【Luogu P4091】求和(NTT)

    题面 Bzoj Luogu 题解 先来颓柿子 $$ \sum_{i=0}^n\sum_{j=0}^iS(i,j)2^jj! \\ =\sum_{j=0}^n2^jj!\sum_{i=0}^nS(i,j ...

  9. Luogu 4091 [HEOI2016/TJOI2016]求和

    BZOJ 4555 一道模板题. 第二类斯特林数有公式: $$S(n, m) = \frac{1}{m!}\sum_{i = 0}^{m}(-1)^i\binom{m}{i}(m - i)^n$$ 考 ...

随机推荐

  1. Linux 虚拟机绑定静态 IP

    环境介绍 Machine: NUC8i5BEK OS: macOS Catalina 10.15.6 VirtualBox: 6.1.12 r139181 (Qt5.6.3) CentOS: 8.2. ...

  2. XSS基础笔记 from 《Web安全攻防 渗透测试实战指南》

    XSS漏洞介绍 跨站脚本(Cross Site Scripting, 简称为XSS或跨站脚本或跨站脚本攻击)是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种.它允许恶意用户将代码注入网页,其 ...

  3. C++实现职工管理系统(中)

    C++实现职工管理系统(中) 大家好,今天是在博客园的第九天,博主今天给大家带来的是职工管理系统(C++)(中) 这次的随笔记录是实现(上)结语处说的几个功能 目录 C++实现职工管理系统(中) 1. ...

  4. python 魔法方法诠释

    什么是Python魔法方法 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加"魔法"的特殊方法. 它们经常是两个下划线包围来命名的(比如 ini ...

  5. spring aop 源码分析(三) @Scope注解创建代理对象

    一.源码环境的搭建: @Component @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON,proxyMode = ScopedP ...

  6. 一加云耳2和一加云耳z区别

    [解码方式]:云耳Z采用的音源解码方式是AAC,云耳2使用的是APTX: [发声单元]:云耳Z采用的是动圈,云耳2采用的是动圈+动铁组合 [颜色]:云耳Z有4款颜色(宝蓝.薄荷绿.黑色.米白)云耳2有 ...

  7. Java学习day02

    day02-课堂笔记 1.打开DOS命令窗口,执行java HelloWorld,执行原理? * java.exe命令会启动JVM * JVM启动之后会启动类加载器ClassLoader * Clas ...

  8. 【CSP2019-J】游记

    看我朋友们的博客里面都写了游记,我也来凑个热闹(雾) day1# 介于是\(CSP-J\),我们是比赛当天走的,上午卡点到.一路上不允许玩游戏,于是就在路上看了一路的鬼畜视频,然后看了看对拍的板子(然 ...

  9. DM8数据库备份还原的原理及应用

    (本文部分内容摘自DM产品技术支持培训文档,如需要更详细的文档,请查询官方操作手册,谢谢) 一.原理 1.DM8备份还原简介 1.1.基本概念 (1)表空间与数据文件 ▷ DM8表空间类型: ▷ SY ...

  10. 这就是小学生也会用的四则计算练习APP吗?- by软工结对编程项目作业

    结对编程项目 软件工程 这就是链接 作业要求 这就是链接 作业目标 熟悉在未结对情况下如何结对开发项目 Github与合作者 合作者(学号): 区德明:318005422 虚左以待 Github链接: ...