2018.5.23 T2前缀!

前缀!
(b.cpp/c/pas)
Time Limit:3 Sec Memory Limit:256 MB
Description
那熙凤又问黛黛道:“我这有道题不知妹妹会不会做。”黛黛道:“且说。”熙凤笑道:“题目是这样的:
定义f0(x)=Ax,fn(x)= sigma[fn-1(i) |i<=x]。给出长度为N 的数组A(从1~N 编号)和Q 个

操作。操作有两种:

Add i j 表示将Ai的值加上j(j≤P);

Query i j 表示询问fi(j)的值(i≤M),由于答案可能会很大,给我mod P 后的答案即可,P=1,000,000,007。”

Input
第一行为三个正整数N、M、Q。
第二行为N 个非负整数,表示A 数组。
接下来Q 行,每行表示一个操作,Add i j 或Query i j。
Output
输出有多行,每行表示fi(j) mod P。
Sample Input
4 4 4
1 1 1 1
Query 0 4
Query 4 3
Add 1 1
Query 3 2
Sample Output
1
15

7


Data Limitation
对于10%的数据:M≤100。
对于30%的数据:Q≤400。
对于50%的数据:N≤10。
对于70%的数据:N≤100。

对于100%的数据:N,M,Q≤4000。

——————————————————————————————————————————

观察一下样例,首先它的递推式一看就是杨辉三角,再对比add前后

将 A0+1,发现 f1~f4的增量

1 1 1  1
1 2 3  4
1 3 6  10
1 4 10 20

发现还是个杨辉三角,加2是两个杨辉三角,这显然可以乘起来

对于query加上每个三角即可

#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
#define int long long
const int N=4005,P=1e9+7;
int n,m,Q;
int f[N][N],yh[N][N],ad[N];
string a,b="Query";
signed main() {
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	scanf("%lld%lld%lld",&n,&m,&Q);
	for (int i=1;i<=n;i++)
		scanf("%lld",&f[0][i]);
	for (int i=1;i<=m;i++)
		for (int j=1;j<=n;j++)
			f[i][j]=(f[i][j-1]+f[i-1][j])%P;
	for (int i=1;i<=n;i++)
		yh[1][i]=1;
	for (int i=2;i<=m;i++)
		for (int j=1;j<=n;j++)
			yh[i][j]=(yh[i-1][j]+yh[i][j-1])%P;
	while (Q--) {
		int x,y;
		cin>>a>>x>>y;
		if (a==b) {
			int res=0;
			for (int i=1;i<=y;i++) {
				res=(res+yh[x][y-i+1]*ad[i]%P)%P;
			}
			printf("%lld\n",(f[x][y]+res)%P);
		}
		else {
			f[0][x]=(f[0][x]+y)%P;
			ad[x]=(ad[x]+y)%P;
		}
	}
}                                       

猜你喜欢

转载自blog.csdn.net/qq_41893580/article/details/80424648
T2