列表

详情


NC200047. Minus K

描述

Cirno (⑨) 具有操纵冷气程度的能力,某一天,Cirno想要改进她的冻符「Minus K」,具体地说,她想要做这样一件事:

Cirno首先会放出1个冰块,这里记作ICE_0
之后她会控制这个冰块使其分裂,这里将ICE_0分裂产生的冰块记作ICE_1
之后她可能会再次控制全部ICE_1使其分裂,使其变成新的冰块,记作ICE_2,以此类推。

形式化地,对于冰块ICE_i,进行分裂后会得到冰块,并且只要Cirno下定决心将某一种冰块分裂,全部此种冰块都会被分裂。
定义一个计数函数cnt(x),表示冰块x总共产生过多少个。

显然最初的冰块ICE_0只有一个,即
Cirno会将ICE_0分裂成k_1ICE_1,所以
以此类推,Cirno总会将每个ICE_i分裂成

Cirno会分裂冰块n次,之后Cirno想知道从ICE_lICE_r的每种冰块总共出现了多少次(包含ICE_lICE_r),因为结果可能很大,无法使用普通的整型存放下,所以请将结果对20090909取模。

形式化表述为,对于每次询问,输出的值。

输入描述

输入第一行包含两个正整数n和q,之间使用一个空格符分隔,表示Cirno分裂冰块的次数,以及询问次数。
之后第二行包含n个正整数,相邻正整数之间使用一个空格符分隔,按照输入顺序的第i个正整数记作k_i,表示会将冰块分裂成k_i块冰块ICE_i
之后连续输入q行,每行一个两个非负整数,之间使用一个空格符分隔,这种输入的第i行的两个整数记作,即题目描述中的每次询问。

数据规范:
* .
* .
* .

输出描述

输出q行,每行一个正整数,即按照输入顺序依次回答每次询问。

示例1

输入:

2 6
2 3
0 0
1 1
2 2
0 1
1 2
0 2

输出:

1
2
6
3
8
9

说明:

原站题解

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

C++14(g++5.4) 解法, 执行用时: 71ms, 内存消耗: 2792K, 提交时间: 2019-12-07 16:52:58

#include<cstdio>
#include<algorithm>
using namespace std;

#define ll long long
const int MOD=20090909;
const int Mn=1e5+17;
ll a[Mn],sum[Mn];

int main(){
	int n,q;scanf("%d%d",&n,&q);
	a[1]=1;
	for(int i=2;i<=n+1;++i) scanf("%lld",&a[i]);
	for(int i=2;i<=n+1;++i) a[i]=(a[i]*a[i-1])%MOD;
	for(int i=1;i<=n+1;++i) sum[i]=(sum[i-1]+a[i])%MOD;
	while(q--){
		int l,r;scanf("%d%d",&l,&r);
		printf("%lld\n",(sum[r+1]-sum[l]+MOD)%MOD);
	}
	return 0;
}

C(clang 3.9) 解法, 执行用时: 81ms, 内存消耗: 4428K, 提交时间: 2019-12-12 21:21:42

#include<stdio.h>
#define N 20090909
int main()
{
	int i,n,q,b,c,d;
	scanf("%d%d",&n,&q);
	long long a[100009];
	a[0]=1;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&b);
        a[i]=a[i-1]*b%N;
	}
	long long k[100009];
	k[0]=1;
	for(i=1;i<=n;i++)
	{
		k[i]=(k[i-1]+a[i])%N;	
	}
	for(i=1;i<=q;i++)
	{
		scanf("%d%d",&c,&d);
		if(c==0)printf("%d\n",k[d]);
		else printf("%lld\n",(k[d]-k[c-1]+N)%N);
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 88ms, 内存消耗: 2020K, 提交时间: 2020-02-16 15:47:17

#include<bits/stdc++.h>
using namespace std;
int mod=20090909;
long long s[100000],b;
int main()
{
	int n,q,a,l,r;
	scanf("%d%d",&n,&q);
	s[0]=1;b=1;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a);
		b=b*a%mod;
		s[i]=(s[i-1]+b)%mod;
	}
	while(q--)
	{
		scanf("%d%d",&l,&r);
		if(l==0) b=0;
		else b=s[l-1];
		printf("%lld\n",(s[r]+mod-b)%mod);
	}
	return 0;
 } 

上一题