线段树。

线段树维护区间矩阵和,操作都是最简单的线段树。$lazy$标记不要记录乘了几次,直接记录乘了几次之后的矩阵就可以了,不然每次下传的时候再算一遍时间复杂度会提高。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<bitset>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c=getchar(); x=;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) {x=x*+c-''; c=getchar();}
} int mod=1e9+;
const int maxn=;
struct Matrix
{
int A[][]; int R,C;
}s[*maxn],t[*maxn];
int n,m;
Matrix Q,Z,P; Matrix ch(Matrix a,Matrix b)
{
Matrix c;
int i, j, k;
for (i = ; i <= a.R; i++)
for (j = ; j <= b.C; j++){
c.A[i][j]=;
for (k = ; k <= a.C; k++){
LL aa=(LL)a.A[i][k],bb=(LL)b.A[k][j];
LL cc=aa*bb%(LL)mod;
int dd=(int)cc;
c.A[i][j] = (c.A[i][j] + dd)%mod;
}
}
c.R=a.R; c.C=b.C;
return c;
} Matrix pow(LL p)
{
Matrix X,Y; X.R=; X.C=; Y.R=; Y.C=; Y.A[][]=; Y.A[][]=;
Y.A[][]=; Y.A[][]=; X.A[][]=; X.A[][]=;
X.A[][]=; X.A[][]=; while (p)
{
if (p % == ) Y = ch(Y,X);
p = p >> ;
X = ch(X,X);
}
return Y;
} void pushUp(int rt)
{
s[rt].R=; s[rt].C=;
s[rt].A[][]=(s[*rt].A[][]+s[*rt+].A[][])%mod;
s[rt].A[][]=(s[*rt].A[][]+s[*rt+].A[][])%mod;
s[rt].A[][]=(s[*rt].A[][]+s[*rt+].A[][])%mod;
s[rt].A[][]=(s[*rt].A[][]+s[*rt+].A[][])%mod;
} bool check(Matrix x)
{
if(x.A[][]!=) return ;
if(x.A[][]!=) return ;
if(x.A[][]!=) return ;
if(x.A[][]!=) return ;
return ;
} void pushDown(int rt)
{
if(check(t[rt])==) return; s[*rt]=ch(s[*rt],t[rt]); t[*rt]=ch(t[*rt],t[rt]);
s[*rt+]=ch(s[*rt+],t[rt]); t[*rt+]=ch(t[*rt+],t[rt]); t[rt].A[][]=; t[rt].A[][]=;
t[rt].A[][]=; t[rt].A[][]=;
} void build(int l,int r,int rt)
{
t[rt].A[][]=; t[rt].A[][]=;
t[rt].A[][]=; t[rt].A[][]=;
t[rt].R=; t[rt].C=; if(l==r)
{
LL x; scanf("%lld",&x); s[rt].R=; s[rt].C=;
s[rt].A[][]=; s[rt].A[][]=;
s[rt].A[][]=; s[rt].A[][]=; s[rt]=ch(s[rt],pow(x-));
return;
} int m=(l+r)/;
build(l,m,*rt);
build(m+,r,*rt+);
pushUp(rt);
} void update(int L,int R,LL x,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
s[rt]=ch(s[rt],P);
t[rt]=ch(t[rt],P);
return ;
} int m=(l+r)/;
pushDown(rt);
if(L<=m) update(L,R,x,l,m,*rt);
if(R>m) update(L,R,x,m+,r,*rt+);
pushUp(rt);
} void add(Matrix a)
{
Q.A[][]=(Q.A[][]+a.A[][])%mod;
Q.A[][]=(Q.A[][]+a.A[][])%mod;
Q.A[][]=(Q.A[][]+a.A[][])%mod;
Q.A[][]=(Q.A[][]+a.A[][])%mod;
} void get(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) { add(s[rt]); return ; } int m=(l+r)/;
pushDown(rt);
if(L<=m) get(L,R,l,m,*rt);
if(R>m) get(L,R,m+,r,*rt+);
pushUp(rt);
} int main()
{
scanf("%d%d",&n,&m);
build(,n,);
for(int i=;i<=m;i++)
{
int op; scanf("%d",&op);
int L,R; scanf("%d%d",&L,&R);
if(op==)
{
LL x; scanf("%lld",&x);
P=pow(x); update(L,R,x,,n,);
}
else
{
Q.R=; Q.C=; memset(Q.A,,sizeof Q.A);
get(L,R,,n,);
Z.R=; Z.C=; Z.A[][]=; Z.A[][]=;
Z=ch(Z,Q);
printf("%d\n",Z.A[][]);
}
}
return ;
}

CodeForces 718C Sasha and Array的更多相关文章

  1. Codeforces 718C. Sasha and Array(线段树)

    传送门 解题思路: 这道题给了我们一个崭新的角度来看线段树. 我们常常使用的线段树是维护区间的函数的. 这里呢,提示我们线段树其实还可以维护递推. 美好的矩阵递推性质支持了这一功能. 或者说,对于递推 ...

  2. 718C Sasha and Array

    传送门 题目 Sasha has an array of integers a1, a2, ..., an. You have to perform m queries. There might be ...

  3. [CF 718C] Sasha and Array

    传送门 Solution 用线段树维护矩阵 第一个操作相当于区间乘 第二个操作相当于区间求和 Code  #include<bits/stdc++.h> #define ll long l ...

  4. 【codeforces 718 C&D】C. Sasha and Array&D. Andrew and Chemistry

    C. Sasha and Array 题目大意&题目链接: http://codeforces.com/problemset/problem/718/C 长度为n的正整数数列,有m次操作,$o ...

  5. Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵

    E. Sasha and Array 题目连接: http://codeforces.com/contest/719/problem/E Description Sasha has an array ...

  6. codeforces 719E E. Sasha and Array(线段树)

    题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...

  7. Codeforces Round #373 (Div. 2) E. Sasha and Array 矩阵快速幂+线段树

    E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input standard ...

  8. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  9. Codeforces 442C Artem and Array(stack+贪婪)

    题目连接:Codeforces 442C Artem and Array 题目大意:给出一个数组,每次删除一个数.删除一个数的得分为两边数的最小值,假设左右有一边不存在则算作0分. 问最大得分是多少. ...

随机推荐

  1. Solr 教程

    1.Solr安装 下载jdk-8u111-windows-i586_8.0.1110.14 下载solr-6.3.0.zip 2.配置JAVA_HOME 在"系统变量"中,设置3项 ...

  2. 使用javaservice 将jboss 注册为服务

    近来做项目,需要jboss定期重新启动.不想再看到jboss启动那个黑洞洞的窗口,就想着把它注册为服务,然后在net start.恰好objectweb上有个open source的javaservi ...

  3. Unit of work + Repository

    (Unit of work + Repository) 今日后开启进阶模式! 谈到MVC与EntityFramework,则不得不说一说事务与仓储(Unit of work + Repository) ...

  4. 利用servlet产生随机数,原理是获取Graphics对象进行绘图

    public class ResonpeRandomImgDemo extends HttpServlet { int width=100; int height=30; public void do ...

  5. openGL的使用步骤

    使用openGL步骤:1.创建GLSurfaceView对象2.创建GLSurfaceView.renderer实现类.3.设置activity的contentView,以及设置view的render ...

  6. 关于FragmentManager动态管理Fragment时Fragment生命周期的探究

    Fragment是Android中的重要组件,在Android 3.0的时候添加进来. 关于Fragment的生命周期,我相信了解过的开发人员都应该把以下方法脱口而出:onAttach, onCrea ...

  7. 让大蛇(Python)帮你找工作

    前段时间用Python实现了一个网络爬虫(让大蛇(Python)帮你找工作),效率总体还可以,但是缺点就是每次都需要手动的去触发,于是打算对该爬虫加上Timer,经过网上一番搜索以及API的查询,发现 ...

  8. iOS基础 - 多媒体

    一.播放视频 iOS提供了叫做MPMoviePlayerController.MPMoviePlayerViewController的两个类,可以用来轻松播放视频 YouTobe就是用MPMovieP ...

  9. 从网络上获取图片并保存在sdCard上

    package com.aib.soft; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileO ...

  10. .Net 异步随手记(一)

    今天要记录的内容摘要是: 什么时候异步代码能“等”在那里,什么时候不会“等” 这两天Coding的时候碰到一个事儿,就是想让异步等在那里结果却直接执行过去了,比如这样: async static vo ...