列表

详情


NC200011. 雷顿女士与选书

描述

卡特莉为了提高自己的知识水平,决定去图书馆借一些书来学习。

现在图书馆有顺序排列着编号1至n的分馆,每个分馆里的书籍都属于不同的知识领域。

由于图书馆刚刚新建,一开始所有的分馆都没有书籍。

但是随着时间的推移,其中的某个分馆会扩充自己的藏书。

并且在某个时刻卡特莉可能会去借书,由于她懒得走太远,她只会在编号在l至r之间的分馆借书,并且她每次不会在同一个领域借多本书籍(这就意味着她每次最多只会在一个分馆借一本书)。

每次她在借书之前希望知道自己有多少种方案能恰好借到k本书,请你每次帮她求出答案。

具体的来说,我们一共有n座分馆,一开始每个图书馆的藏书数量都为0。

接下来我们会有m个时刻。

我们按顺序给出这m个时刻的操作,每个时刻有一个op。

如果op=1,那么接下来输入pos,x,表示编号为pos的图书馆藏书增加x。

如果op=2,那么接下来输入l,r,k,表示查询从编号l至r的图书馆恰好借k本书的方案数。

我们认为所有的书都是不同的,两个方案之间只要有一本书不同我们就认为它们是不同的方案。

输入描述

第一行输入一个T()表示数据组数。


接下来T组数据。

对于每组数据,第一行输入n,m(),分别表示图书馆的数量和时刻的数量。
接下来有m行,每行输入1,pos,x()或者2,l,r,k()。

输出描述

对于每次查询,输出一个数字表示答案,由于答案可能很大,请将答案对取模后输出。

请注意,行末不要输出多余空格。

示例1

输入:

1
3 8
2 1 3 1
1 1 2
2 1 3 1
2 1 3 2
1 2 1
2 2 2 1
2 1 3 1
2 1 3 2

输出:

0
2
0
1
3
2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 651ms, 内存消耗: 2536K, 提交时间: 2019-12-08 15:45:15

#include<bits/stdc++.h>

using namespace std;
const int mod=1e9+7;
const int maxn=1e4+5;
int t,n,m;
struct node{
	int num[11];
	node(){
		memset(num,0,sizeof(num));
	}
	node operator+(const node&a)const{
		node p;
		for (int i=0;i<=10;i++)
			for (int j=0;j<=10-i;j++){
				if (i+j>10) continue;
				p.num[i+j]=(p.num[i+j]+1ll*num[i]*a.num[j]%mod)%mod;
			}
		return p;
	}
}tree[maxn<<2];
void build(int l,int r,int k){
	if (l==r){
		tree[k]=node();
		tree[k].num[0]=1;
		return;
	}
	int mid=l+r>>1;
	build(l,mid,k*2);
	build(mid+1,r,k*2+1);
	tree[k]=tree[k*2]+tree[k*2+1];
}
int cnt[maxn];
void update(int pos,int l,int r,int k,int c){
	if (pos<l||pos>r) return;
	if (l==r){
		tree[k].num[1]=cnt[l];
		return;
	}
	int mid=l+r>>1;
	update(pos,l,mid,k*2,c);
	update(pos,mid+1,r,k*2+1,c);
	tree[k]=tree[k*2]+tree[k*2+1];
}
node E;
node query(int L,int R,int l,int r,int k){
	if (l>R||L>r) return E;
	if (L<=l&&R>=r)	return tree[k];
	int mid=l+r>>1;
	return query(L,R,l,mid,k*2)+query(L,R,mid+1,r,k*2+1);
}
int main(){
	scanf("%d",&t);
	E.num[0]=1;
	while (t--){
		scanf("%d%d",&n,&m);
		for (int i=1;i<=n;i++)
			cnt[i]=0;
		build(1,n,1);
		for (int i=1,op,pos,x,l,r,k;i<=m;i++){
			scanf("%d",&op);
			if (op==1){
				scanf("%d%d",&pos,&x);
				cnt[pos]+=x;
				update(pos,1,n,1,x);
			}else{
				scanf("%d%d%d",&l,&r,&k);
				node u = query(l,r,1,n,1);
				cout << u.num[k] << '\n';
			}
		}
	}
} 

上一题