前缀!
(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 个
第一行为三个正整数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
(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; } } }