cf316e3

点击打开链接

博客讲的很好了,我自己写了250行,wa了十几次。。

Is life always this hard,or is it just when you are a kid? 
人生总是那么痛苦吗?还是只有小时候是这样? 
Always like this. 
总是如此。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<cctype>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<iomanip>
#include<sstream>
#include<cstdlib>
#include<ctime>
#include<list>
#include<deque>
#include<bitset>
#include<fstream>
#define ld double
#define ull unsigned long long
#define ll long long
#define pii pair<int,int >
#define iiii pair<int,pii >
#define mp make_pair
#define INF 1000000000
#define MOD 1000000007
#define rep(i,x) for(int (i)=0;(i)<(x);(i)++)
#define putchar IO::_putchar
#define getchar IO::_getchar
namespace IO
{
	const int sz=1<<15;
	char inbuf[sz],outbuf[sz];
	char *pinbuf=inbuf+sz;
	char *poutbuf=outbuf;
	inline char _getchar() 
	{
		if (pinbuf==inbuf+sz)fread(inbuf,1,sz,stdin),pinbuf=inbuf;
		return *(pinbuf++);
	}
	inline void _putchar(char x)
	{
		if (poutbuf==outbuf+sz)fwrite(outbuf,1,sz,stdout),poutbuf=outbuf;
		*(poutbuf++)=x;
	}
	inline void flush() 
	{
		if (poutbuf!=outbuf)fwrite(outbuf,1,poutbuf-outbuf,stdout),poutbuf=outbuf;
	}
}
inline int getint()
{
	int x=0,p=1;char c=getchar();
	while (c<=32)c=getchar();
	if(c==45)p=-p,c=getchar();
	while (c>32)x=x*10+c-48,c=getchar();
	return x*p;
}
void put_int(int x)
{
	if(x==0)return;
	put_int(x/10);putchar(x%10+48);
}
void putint(int x)
{
	if(x==0)putchar(48);
	else
	{
		if(x<0)putchar(45),x=-x;
		put_int(x);
	}
	putchar('\n');
}
//
const int maxn=2e5+5;
const int mod=1e9;
inline int add(int x,int y)
{
	return x+y>mod?x+y-mod:x+y;
}
inline int mul(int x,int y)
{
	return (1ll*x*y)%mod;
}
struct M
{
	int d[2][2];
	M(int x=0)
	{
		rep(i,2)rep(j,2)d[i][j]=1ll*(i==j)*x;
	}

	M operator *(const M &b)const
	{
		M ans;
		rep(i,2)rep(j,2)rep(k,2)
			ans.d[i][j]=add(ans.d[i][j],mul(d[i][k],b.d[k][j]));
		return ans;	
	}
	M operator +(const M &b)const 
	{
		M ans;
		rep(i,2)rep(j,2)ans.d[i][j]=add(d[i][j],b.d[i][j]);
		return ans;
	}
};
M mm[maxn];
bool ok[maxn];
inline M modpow(int y)
{
	if(ok[y])return mm[y];
	ok[y]=true;
	M ans(1);
	ans=modpow(y>>1)*modpow(y>>1);
	if(y&1)ans=ans*mm[1];
	return mm[y]=ans;
}
int a[maxn],n,t,fib[maxn],pre[maxn];
struct node
{
	M s;
	int len;
	node(){len=0;}
	node(M _s,int _len){s=_s,len=_len;}
	node operator +(const node &b)const 
	{
		if(len<=0)return b;
		if(b.len<=0)return *this;
		return node(s+b.s*modpow(len),len+b.len);
	}
	void operator +=(ll b)
	{
		 s.d[0][0]=add(s.d[0][0],mul(pre[len-1],b));
		 s.d[0][1]=add(s.d[0][1],mul(pre[len]-1,b));
	}
	int v(){return s.d[0][0];}
};
namespace T
{
	int m=1;
	ll lazy[maxn<<2]={0};
	node dat[maxn<<2];
	void build(int k,int l,int r)
	{
		if(r-l<=1)
		{
			dat[k].len=1;
			dat[k].s.d[0][0]=dat[k].s.d[0][1]=a[l];
			return;
		}
		build(2*k+1,l,(l+r)>>1);
		build(2*k+2,(l+r)>>1,r);
		dat[k]=dat[2*k+1]+dat[2*k+2];
	}
	void pushdown(int k,int l,int r)
	{
		if(lazy[k]==0||r-l==1)return;
		lazy[2*k+1]=add(lazy[2*k+1],lazy[k]);
		lazy[2*k+2]=add(lazy[2*k+2],lazy[k]);
		dat[2*k+1]+=lazy[k];
		dat[2*k+2]+=lazy[k];
		lazy[k]=0;
	}
	node query(int x,int y,int l,int r,int k)
	{
		pushdown(k,l,r);
		if(l>=y||r<=x)return node(M(0),0);
		else if(x<=l&&r<=y)return dat[k];
		else 
		{
			node lx=query(x,y,l,(l+r)>>1,2*k+1);
			node ly=query(x,y,(l+r)>>1,r,2*k+2);
			return lx+ly;
		}
	}
	void modify(int x,int y,int l,int r,int k,ll del)
	{
		pushdown(k,l,r);
		if(l>=y||r<=x)return;
		else if(x<=l&&r<=y)
		{
			lazy[k]+=del;
			dat[k]+=del;
			pushdown(k,l,r);
		}
		else
		{
			modify(x,y,l,(l+r)>>1,2*k+1,del);
			modify(x,y,(l+r)>>1,r,2*k+2,del);
			dat[k]=dat[2*k+1]+dat[2*k+2];
		}
	}                              
	void fM(int x,int l,int r,int k,ll del)
	{
		pushdown(k,l,r);
		if(r-l==1)dat[k].s.d[0][0]=dat[k].s.d[0][1]=del;
		else
		{
			int mid=(l+r)>>1;
			if(x<mid)fM(x,l,mid,2*k+1,del);
			else fM(x,mid,r,2*k+2,del);
			dat[k]=dat[2*k+1]+dat[2*k+2];
		}
	}
}
void finit()
{
	ok[0]=true;
	mm[0].d[0][0]=mm[0].d[1][1]=1;
	ok[1]=true;
	mm[1].d[0][1]=mm[1].d[1][0]=mm[1].d[1][1]=1;
	fib[0]=fib[1]=pre[0]=1;pre[1]=2;
	for(int i=2;i<maxn;i++)
	{
		fib[i]=add(fib[i-1],fib[i-2]);
		pre[i]=add(pre[i-1],fib[i]);
	}
	n=getint();t=getint();
	rep(i,n)a[i]=getint();
	T::build(0,0,n);
}
void solve()
{
	rep(i,t)
	{
		int op=getint(),x=getint()-1,y=getint();
		if(op==1)T::fM(x,0,n,0,y);
		else if(op==2)putint(T::query(x,y,0,n,0).v());
		else
		{
			ll del=getint();
			T::modify(x,y,0,n,0,del);
		}
	}
	IO::flush();
}
int main()
{
	finit();
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值