B 君的第二题 (hongkong)

题目大意:

一个长度为\(n(n\le2\times10^5)\)的数组,给定一个数\(k(k\le40)\)。用\(a[i][j]\)表示该数组\(i\)次前缀和中第\(j\)项的值,要求支持以下两种操作:

  1. 输入\(x,y\),将\(a[0][x]\)加上\(y\);
  2. 输入\(x\),求\(a[k][x]\)的值。

思路:

题目询问的实际上就是\(\sum_{i=1}^x\binom{x-i+k-1}{k-1}a[0][i]\)。

我们可以得到

\[\begin{align*}
&\sum_{i=1}^x\binom{x-i+k-1}{k-1}a[0][i]\\
=&\sum_{i=1}^x\sum_{j=0}^{k-1}\binom xj\binom{k-i-1}{k-j-1}a[0][i]\\
=&\sum_{j=0}^{k-1}\binom xj\left(\sum_{i=1}^x\binom{k-i-1}{k-j-1}a[0][i]\right)
\end{align*}
\]

用树状数组维护即可。

时间复杂度\(\mathcal O(mk\log n)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
using int64=long long;
constexpr int N=4e5+1,K=41,mod=1e9+7;
int n,m,k,fac[N],ifac[N];
void exgcd(const int &a,const int &b,int &x,int &y) {
if(!b) {
x=1,y=0;
return;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
inline int inv(const int &x) {
int ret,tmp;
exgcd(x,mod,ret,tmp);
return (ret%mod+mod)%mod;
}
inline int C(const int &n,const int &m) {
if(n<m) return 0;
return (int64)fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
class FenwickTree {
private:
int val[K][N];
int lowbit(const int &x) const {
return x&-x;
}
int query(const int &p,const int &v) const {
int ret=0;
if(v==0) return val[k][p];
for(register int i=1;i<=k;i++) {
(ret+=(int64)val[i][p]*C(v+k-i-1,v-1)%mod)%=mod;
}
return ret;
}
public:
int query(const int &p) const {
int ret=0;
for(register int i=p;i;i-=lowbit(i)) {
(ret+=query(i,p-i))%=mod;
}
return ret;
}
void modify(const int &p,const int &x) {
for(register int i=1;i<=k;i++) {
for(register int j=p;j<=n;j+=lowbit(j)) {
(val[i][j]+=(int64)C(i+j-p-1,i-1)*x%mod)%=mod;
}
}
}
};
FenwickTree t;
int main() {
n=getint(),m=getint(),k=getint();
for(register int i=fac[0]=1;i<=n*2;i++) {
fac[i]=(int64)fac[i-1]*i%mod;
}
ifac[n*2]=inv(fac[n*2]);
for(register int i=n*2;i;i--) {
ifac[i-1]=(int64)ifac[i]*i%mod;
}
for(register int i=0;i<m;i++) {
const int opt=getint();
if(opt==0) {
const int x=getint(),y=getint();
t.modify(x,y);
}
if(opt==1) {
printf("%d\n",t.query(getint()));
}
}
return 0;
}

最新文章

  1. Go结构体实现类似成员函数机制
  2. Leetcode Maximum Product Subarray
  3. hdu-5977 Garden of Eden(树分治)
  4. BCP 导出导入数据(SQL Server)
  5. poj1125&amp;zoj1082Stockbroker Grapevine(Floyd算法)
  6. Android Bundle、Handler和Message类介绍
  7. android studio开发工具的android library打包文件(.aar)本地引用
  8. Python 自带IDLE中调试程序
  9. linux df和du统计的空间不一致
  10. Linux CentOS7.0 (03)安装验证 docker
  11. List数组和集合相互转换
  12. 基于ELK5.1(ElasticSearch, Logstash, Kibana)的一次整合测试
  13. PMP知识点(五)——资源管理表示方法
  14. gitlab安装后吃内存的解决办法
  15. sparksql udf自定义函数中参数过多问题的解决
  16. GsonUtil工具类
  17. PHP Excel导入日期单元格处理
  18. python if __name__ == &#39;main&#39; 的作用和原理()
  19. 编译时:virtual memory exhausted: Cannot allocate memory,常见于VPS
  20. JavaScript如何实现拖放功能

热门文章

  1. CentOS在ssh下远程重装系统
  2. 超级rtmp服务器和屌丝wowza
  3. java实现数据库分页
  4. IE7下面iframe滚动条无法用鼠标轮滚 其他浏览器可以
  5. vue 同页面不同参数
  6. poj 1426(同余搜索)
  7. hdu 1428(很好的一道题,最短路+记忆化搜索)
  8. Python3判断自身脚本是不是在运行
  9. Linux下安装rz、sz命令(文件上传下载)
  10. Jenkins+maven+Tomcat配置发布