【题解】[CF718C Sasha and Array]
【题解】CF718C Sasha and Array
对于我这种喜欢写结构体封装起来的选手这道题真是太对胃了\(hhh\)
一句话题解:直接开一颗线段树的矩阵然后暴力维护还要卡卡常数
我们来把\(2 \times 2\)看做之后时间复杂度就是\(O(nlogn)\)。
写了一点点这种线段树维护除了数字之外的东西的题目,一个最大的感受就是递归用\(void\),传答案什么的一个全局变量,这样比较快。
需要注意的点是\(lazy \ \ tag\)要随着\(seg\)一起初始化一下。
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
#define lef l,mid,pos<<1
#define rgt mid+1,r,pos<<1|1
TMP inline ccf qr(ccf b){
register char c=getchar();register int q=1;register ccf x=0;
while(c<48||c>57)q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
return q==-1?-x:x;}
TMP inline ccf Max(ccf a,ccf b){return a<b?b:a;}
TMP inline ccf Min(ccf a,ccf b){return a<b?a:b;}
TMP inline ccf Max(ccf a,ccf b,ccf c){return Max(a,Max(b,c));}
TMP inline ccf Min(ccf a,ccf b,ccf c){return Min(a,Min(b,c));}
TMP inline ccf READ(ccf* _arr,int _n){RP(t,1,_n)_arr[t]=qr((ccf)1);}
//----------------------template&IO---------------------------
const int mod=1e9+7;
const int maxn=1e5+5;
struct MTX{
ll data[2][2];
MTX(){data[0][0]=data[0][1]=data[1][0]=data[1][1]=0;}
inline ll* operator[](int x){return data[x];}
inline void operator *=(MTX a){
MTX ret;
RP(k,0,1)RP(i,0,1)RP(t,0,1)ret[t][i]=(ret[t][i]+data[t][k]*a[k][i])%mod;
*this=ret;}
inline void unis(){data[0][1]=data[1][0]=data[1][1]=1;data[0][0]=0;}
inline void cle() {*this=MTX();RP(t,0,1)data[t][t]=1;}
inline void operator ^=(int x){
MTX base=*this,ret;RP(t,0,1) ret[t][t]=1;
for(register int t=x;t;t>>=1,base*=base)if(t&1)ret*=base;
*this=ret;}
inline void operator +=(MTX x){RP(t,0,1)RP(i,0,1)data[t][i]=(data[t][i]+x[t][i])%mod;}
inline void pr(){RP(t,0,1){RP(i,0,1)cout<<data[t][i]<<' ';cout<<endl;}cout<<endl;}
}seg[maxn<<2],laz[maxn<<2];
bool lz[maxn<<2];
MTX ret,md;
int n,m;
inline void pd(int pos){
if(not lz[pos]) return;
seg[pos<<1]*=laz[pos];
seg[pos<<1|1]*=laz[pos];
laz[pos<<1]*=laz[pos];
laz[pos<<1|1]*=laz[pos];
lz[pos<<1]=lz[pos<<1|1]=1;
laz[pos].cle();lz[pos]=0;
}
inline void pp(int pos){
seg[pos]=MTX();
seg[pos]+=seg[pos<<1];
seg[pos]+=seg[pos<<1|1];
}
void build(int l,int r,int pos){
if(l==r){
seg[pos].unis();
laz[pos].cle();
seg[pos]^=qr(1)-1;
return;
}
midd;laz[pos].cle();
build(lef);build(rgt);
pp(pos);
}
void upd(int L,int R,int l,int r,int pos){
if(L<=l&&r<=R){
laz[pos]*=md;
seg[pos]*=md;
lz[pos]=1;
return;
}midd;pd(pos);
if(L<=mid) upd(L,R,lef);
if(mid< R) upd(L,R,rgt);
pp(pos);
}
void que(int L,int R,int l,int r,int pos){
if(L<=l&&r<=R){
ret+=seg[pos];
return;
}midd;pd(pos);
if(L<=mid) que(L,R,lef);
if(mid< R) que(L,R,rgt);
pp(pos);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=qr(1);m=qr(1);
build(1,n,1);
RP(t,1,m){
register int t1,t2;
if(qr(1)==1){
t1=qr(1);t2=qr(1);
md.unis();md^=qr(1);
upd(t1,t2,1,n,1);
}
else{
t1=qr(1);t2=qr(1);
ret=MTX();
que(t1,t2,1,n,1);
printf("%lld\n",(ret[0][0]+ret[0][1])%mod);
}
}
return 0;
}
【题解】[CF718C Sasha and Array]的更多相关文章
- CF718C Sasha and Array(线段树维护矩阵)
题解 (不会矩阵加速的先去学矩阵加速) 反正我想不到线段树维护矩阵.我太菜了. 我们在线段树上维护一个区间的斐波那契的列矩阵的和. 然后询问时提取每个符合题意列矩阵的答案项(不是列矩阵存了两项吗,一个 ...
- [CF718C] Sasha and Array
Description 给定一个数列,维护两种操作 操作 \(1\),将区间 \([l,r]\) 的数字统一加 \(x\). 操作 \(2\),求 \(\sum \limits_{i=l}^r f(v ...
- CF718C Sasha and Array 线段树+矩阵加速
正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...
- CF718C Sasha and Array 线段树 + 矩阵乘法
有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$ 直接求不好求,改成矩阵乘法的形式: $a_{i}=M^x\times ...
- CF718C Sasha and Array [线段树+矩阵]
我们考虑线性代数上面的矩阵知识 啊呸,是基础数学 斐波那契的矩阵就不讲了 定义矩阵 \(f_x\) 是第 \(x\) 项的斐波那契矩阵 因为 \(f_i * f_j = f_{i+j}\) 然后又因为 ...
- codeforces 719E E. Sasha and Array(线段树)
题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...
- 【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 ...
- 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 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
随机推荐
- Topcoder SRM 668 DIV 2
VerySecureEncryption 模拟 题意: 给你个串message,然后一个置换key,输出置换K次后的结果. 题解: 直接模拟就好. 代码: #include<iostream&g ...
- asp.net获取URL方法
方法如下: Request.Url.ToString()获取完整url(协议名+域名+站点名+文件名+参数):https://localhost:44300/WebForm1.aspx?abc=123 ...
- python pandas相关知识点(练习)
首先引入库文件,并进行数据读取 import pandas as pd import numpy as np data_Base=pd.read_csv("D:\\Exam_Test\\un ...
- OllyDbg 使用笔记 (一)
OllyDbg 使用笔记 (一) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 ollydbg下载地址:http://tools.pediy.com/debuggers.htm ...
- centos 7 安装五笔输入法
centos 7 安装五笔输入法 [a@endv ~]$ yum search wubi 已加载插件:fastestmirror, langpacks Loading mirror speeds fr ...
- mysql下监测数据库语句creating sort index时间过长的问题
在一张单表5000W数据上进行数据查询时传入两个单列索引条件,进行组合索引查询时,如果最后有order by id排序,与去除该排序,性能差距接近两个数量级 结论:在使用列的默认排序时,不应该再ord ...
- 读刘未鹏老大《你应当怎样学习C++(以及编程)》
标签(空格分隔): 三省吾身 原文地址:你应当怎样学习C++(以及编程) 本人反思自己这些年在学校学得稀里糊涂半灌水. 看到这篇文章,感觉收获不少.仿佛有指明自己道路的感觉,当然真正困难的还是坚持学习 ...
- HDFS怎样检測并删除多余副本块
前言 在HDFS中,每时每刻都在进行着大量block块的创建和删除操作,这些庞大的block块构建起了这套复杂的分布式系统.普通block的读写删除操作一般人都或多或少了解过一些,可是过量的副本清理机 ...
- jq:正则表达式
var checkNum = /^[A-Za-z0-9]+$/; 注意没有引号 checkNum.test(这里添加待匹配的字符串); var textNull=/^\s*$/; if(textN ...
- 性能测试框架Multi-Mechanize安装与使用
python模块介绍- multi-mechanize 通用的性能测试工具 简介 Multi-Mechanize 是一个开源的性能和负载测试框架,它并发运行多个 Python 脚本对网站或者服务生成负 ...