列表

详情


NC230082. Sasha and Array

描述

在本题中,我们用 f_i 来表示第 i 个斐波那契数()。
- 给定一个 n 个数的序列 a。有 m 次操作,操作有两种:
1. 将 加上 x
2. 求

输入描述

第一行两个正整数
第二行n个正整数
接下来m行,每行包含下面两种形式中的一种,含义如题面所述:

输出描述

对于每个查询,输出答案。

示例1

输入:

5 4
1 1 2 1 1
2 1 5
1 2 4 2
2 2 4
2 1 5

输出:

5
7
9

说明:

最初,数组a1 , 1 , 2 , 1 , 1 .

第一个询问的答案为: f(1)+f(1)+f(2)+f(1)+f(1)=1+1+1+1+1=5 .

在第二次操作后,数组a 变成 1 , 3 , 4 , 3 , 1 .

第三个询问的答案为: f(3)+f(4)+f(3)=2+3+2=7 .

第四个询问的答案为: f(1)+f(3)+f(4)+f(3)+f(1)=1+2+3+2+1=9 .

原站题解

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

C++ 解法, 执行用时: 673ms, 内存消耗: 25944K, 提交时间: 2022-02-18 03:22:17

#include <iostream>
using namespace std;
#define ll long long
#define int long long 
const int N=1e5+5;
const ll M=1e9+7;
const ll inv2=5e8+4;
using namespace std;

struct Num{
	ll a,b;
	Num():a(1),b(0){}
	Num(ll x,ll y):a(x%M),b(y%M){}
	Num operator +(const Num &B)const{
		return Num(a+B.a,b+B.b);
	}
	Num operator *(const Num &B)const{
		return Num(a*B.a+b*B.b*5,a*B.b+b*B.a);
	}
	Num operator ^(int t)const{
		Num A=(*this),B(1,0);
		while(t){if(t&1)B=B*A;A=A*A;t>>=1;}
		return B;
	}
}eA(inv2,inv2),eB(inv2,-inv2),tr[2][N<<2],lz[2][N<<2];

void pushup(int i,int x){
	tr[i][x]=tr[i][x<<1]+tr[i][x<<1|1];
}
void pushdown(int i,int x){
	tr[i][x<<1]=tr[i][x<<1]*lz[i][x];
	tr[i][x<<1|1]=tr[i][x<<1|1]*lz[i][x];
	lz[i][x<<1]=lz[i][x<<1]*lz[i][x];
	lz[i][x<<1|1]=lz[i][x<<1|1]*lz[i][x];
	lz[i][x].a=1,lz[i][x].b=0;
}
#define ls l,r,L,L+R>>1,x<<1
#define rs l,r,(L+R>>1)+1,R,x<<1|1
void add(int l,int r,int L,int R,int x,int i,Num ad){
	if(l>R||L>r)return;
	if(l<=L&&R<=r){
		tr[i][x]=tr[i][x]*ad;
		lz[i][x]=lz[i][x]*ad;
		return;
	}
	if(L!=R) pushdown(i,x);
	add(ls,i,ad);add(rs,i,ad);
	pushup(i,x);
}
ll query(int l,int r,int L,int R,int x){
	if(l>R||L>r)return 0;
	if(l<=L&&R<=r)return (tr[0][x].b-tr[1][x].b)%M;
	if(L!=R)pushdown(0,x),pushdown(1, x);
	return (query(ls)+query(rs))%M;
}
signed main(){
	int n,m;
	scanf("%lld%lld",&n,&m);
	for(int i=1,a;i<=n;i++){
		scanf("%lld",&a);
		add(i,i,1,n,1,0,eA^a);
		add(i,i,1,n,1,1,eB^a);
	}
	for(int i=1,t,l,r,x;i<=m;i++){
		scanf("%lld%lld%lld",&t,&l,&r);
		if(t==1){
			scanf("%lld",&x);
			add(l,r,1,n,1,0,eA^x);
			add(l,r,1,n,1,1,eB^x);
		}
		else printf("%lld\n",query(l,r,1,n,1));
	}
	return 0;
}

上一题