BZOJ 4085 丧心病狂的毒瘤题目 线段树+矩乘
思路:
一眼矩阵快速幂 再用线段树维护一下矩阵就完了...
我hhhhh 哎我还是too young,too simple 入了这个大坑
线段树维护9个值

以上
如果A+1 转移矩阵是这个样子的

B+1

A-1 B-1 同理行么.....
写了一晚上+一上午 调完了
发现自己被卡常?
我了个大曹
我们发现一开始的矩阵最后一行不变
矩乘的时候特判一发 还是过不去
预处理2^k的矩阵
快速幂的时候省一倍常数 加个快读
80432 ms
卡过去了!!
//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int mod=,N=;
int n,q,a,b,A[N],F[N],d[N][],lazy[N*][];
inline int read(){
int x=;char p=getchar();
while(p<''||p>'')p=getchar();
while(p>=''&&p<='')x=x*+p-'',p=getchar();
return x;
}
struct MATRIX{
int a[][];
void init(){memset(a,,sizeof(a));}
}t[],t0;
int pow(int x,int y){
int res=;
while(y){
if(y&)res=1ll*res*x%mod;
x=1ll*x*x%mod,y>>=;
}return res;
}
MATRIX operator*(MATRIX &a,MATRIX &b){
static MATRIX c;c.init();
for(int i=;i<;i++)
for(int j=;j<;j++){
for(int k=;k<;k++)
c.a[i][j]=(c.a[i][j]+1ll*a.a[i][k]*b.a[k][j])%mod;
}
c.a[][]=;
return c;
}
MATRIX power(int k){
static MATRIX res;res.init();
res.a[][]=res.a[][]=res.a[][]=;
for(int i=;k;k>>=,i++)if(k&)res=res*t[i];
return res;
}
struct Matrix{
int m[][];
void init(){memset(m,,sizeof(m));}
void init1(){
int B[][]={
{,,,,,,,,},
{,,,,,,,,},
{a,,,,,,b,,},
{,a,,,,,,b,},
{,,,,,,,,},
{,,,,a,,,,b},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
};
memcpy(m,B,sizeof(B));
}
void init2(){
int B[][]={
{,,,,,,,,},
{a,,,,b,,,,},
{,,,,,,,,},
{,,a,,,b,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,a,,b},
{,,,,,,,,},
};
memcpy(m,B,sizeof(B));
}
void init3(){
int x,y,z;
if(a){
int inv=pow(a,mod-);
x=inv,y=mod-inv,z=1ll*b*(mod-inv)%mod;
}
else x=,y=,z=mod-b;
int B[][]={
{y,,x,,,,z,,},
{,y,,x,,,,z,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,y,x,,,z},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
};
memcpy(m,B,sizeof(B));
}
void init4(){
int x,y,z;
if(a){
int inv=pow(a,mod-);
x=inv,y=mod-inv,z=1ll*b*(mod-inv)%mod;
}
else x=,y=,z=mod-b;
int B[][]={
{y,x,,,z,,,,},
{,,,,,,,,},
{,,y,x,,z,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,y,x,z},
{,,,,,,,,},
{,,,,,,,,},
};
memcpy(m,B,sizeof(B));
}
}cng[][],I;
Matrix operator*(Matrix &a,Matrix &b){
Matrix c;c.init();
for(int i=;i<;i++)
for(int j=;j<;j++){
for(int k=;k<;k++)
c.m[i][j]=(c.m[i][j]+1ll*a.m[i][k]*b.m[k][j])%mod;
}
return c;
}
void bz(){
cng[][].init1();cng[][].init2();
cng[][].init3();cng[][].init4();
for(int i=;i<;i++){
cng[i][]=I;
for(int j=;j<=;j++)
cng[i][j]=cng[i][j-]*cng[i][j-];
}
}
struct Line{
int m[];
void set(int aa_1,int aa,int bb_1,int bb){
m[]=1ll*aa_1*bb_1%mod,m[]=1ll*aa_1*bb%mod,m[]=1ll*aa*bb_1%mod,
m[]=1ll*aa*bb%mod,m[]=aa_1,m[]=aa,m[]=bb_1,m[]=bb,m[]=;
}
}tr[<<],ans;
Line operator+(Line &a,Line &b){
Line c;
for(int i=;i<;i++)c.m[i]=(a.m[i]+b.m[i])%mod;
return c;
}
Line operator*(Matrix &a,Line &b){
Line c;memset(c.m,,sizeof(c.m));
for(int i=;i<;i++)
for(int j=;j<;j++)
c.m[i]=(c.m[i]+1ll*a.m[i][j]*b.m[j])%mod;
return c;
}
void change(Line &f,Matrix r[],int k){
for(int i=;k;k>>=,i++)if(k&)f=r[i]*f;
}
void calc(int pos,int a0,int a1){
if(a0){
if(a0<)change(tr[pos],cng[],-a0);
else change(tr[pos],cng[],a0);
}
if(a1){
if(a1<)change(tr[pos],cng[],-a1);
else change(tr[pos],cng[],a1);
}
}
void push_down(int pos,int l,int r){
calc(pos,lazy[pos][],lazy[pos][]);
if(l<r){
int lson=pos<<,rson=pos<<|;
lazy[lson][]+=lazy[pos][],lazy[lson][]+=lazy[pos][];
lazy[rson][]+=lazy[pos][],lazy[rson][]+=lazy[pos][];
}
lazy[pos][]=lazy[pos][]=;
}
void push_up(int pos,int l,int r){
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
push_down(lson,l,mid),push_down(rson,mid+,r);
tr[pos]=tr[lson]+tr[rson];
}
void build(int l,int r,int pos){
if(l==r){
tr[pos].set(d[l-][],d[l-][],d[r+][],d[r+][]);
return;
}
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
build(l,mid,lson),build(mid+,r,rson);
push_up(pos,l,r);
}
void insert(int l,int r,int pos,int L,int R,int op){
if(L>R)return;
if(l>=L&&r<=R){
if(!op)lazy[pos][]++;
else if(op==)lazy[pos][]++;
else if(op==)lazy[pos][]--;
else if(op==)lazy[pos][]--;
return;
}push_down(pos,l,r);
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
if(mid<L)insert(mid+,r,rson,L,R,op);
else if(mid>=R)insert(l,mid,lson,L,R,op);
else insert(l,mid,lson,L,R,op),insert(mid+,r,rson,L,R,op);
push_up(pos,l,r);
}
void query(int l,int r,int pos,int L,int R){
if(L>R)return;
push_down(pos,l,r);
if(l>=L&&r<=R){ans=ans+tr[pos];return;}
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
if(mid<L)query(mid+,r,rson,L,R);
else if(mid>=R)query(l,mid,lson,L,R);
else query(l,mid,lson,L,R),query(mid+,r,rson,L,R);
}
signed main(){
scanf("%d%d%d%d",&n,&q,&a,&b);
for(int i=;i<;i++)I.m[i][i]=;
t[].a[][]=t[].a[][]=t[].a[][]=,t[].a[][]=a,t[].a[][]=b;
t0.a[][]=t0.a[][]=,t0.a[][]=;
for(int i=;i<=;i++)t[i]=t[i-]*t[i-];
for(int i=;i<=n;i++){
A[i]=read();
if(A[i]!=){
MATRIX temp=power(A[i]-);temp=temp*t0;
d[i][]=temp.a[][],d[i][]=temp.a[][];
}
else d[i][]=,d[i][]=;
d[i][]=(d[i][]+1ll*d[i][]*a+b)%mod;
d[i][]=(d[i][]+1ll*d[i][]*a+b)%mod;
}bz(),build(,n-,);
while(q--){
char op[];int l,r;
scanf("%s%d%d",op,&l,&r);
if(op[]=='q'){
memset(ans.m,,sizeof(ans.m));
query(,n-,,l+,r-);
printf("%d\n",ans.m[]);
}
else if(op[]=='p')insert(,n-,,l+,min(n-,r+),),insert(,n-,,max(l-,),r-,);
else insert(,n-,,l+,min(n-,r+),),insert(,n-,,max(l-,),r-,);
}
}
BZOJ 4085 丧心病狂的毒瘤题目 线段树+矩乘的更多相关文章
- [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】
题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...
- [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】
题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过 1018,即使它在 ProblemSet 的第一页 ...
- [BZOJ 3888] [Usaco2015 Jan] Stampede 【线段树】
题目链接:BZOJ - 3888 题目分析 首先,计算出每个线段在 x 坐标 0 处出现的时间开始点和结束点,就转成了时间轴上的线段. 然后就是看每条线段是否被 y 比它小的线段完全覆盖了.注意求出的 ...
- bzoj 3489 A simple rmq problem - 线段树
Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...
- bzoj 3237 连通图 - 并查集 - 线段树
Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connected Disconne ...
- BZOJ.4695.最假女选手(线段树 Segment tree Beats!)
题目链接 区间取\(\max,\ \min\)并维护区间和是普通线段树无法处理的. 对于操作二,维护区间最小值\(mn\).最小值个数\(t\).严格次小值\(se\). 当\(mn\geq x\)时 ...
- bzoj 4311 向量 时间线建线段树+凸包+三分
题目大意 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y)点积的最大值是多少.如果当前是空集输出0 分析 按时间线建线段树 大致 ...
- BZOJ 4942 NOI2017 整数 (压位+线段树)
题目大意:让你维护一个数x(x位数<=3*1e7),要支持加/减a*2^b,以及查询x的第i位在二进制下是0还是1 作为一道noi的题,非常考验写代码综合能力,敲+调+借鉴神犇的代码 3个多小时 ...
- BZOJ 2584: [Wc2012]memory(扫描线+线段树)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2584 题意:给出平面n个线段,任意两个线段严格不相交,且每个线段不平行于坐标轴.移 ...
随机推荐
- django中配置允许跨域请求
对于django 安装django-cors-headers,详情请看官方文档 pip install django-cors-headers 配置settings.py文件 a.在INSTALLED ...
- idea 编译级别的设置
File->Settings Project Structure
- Dubbo 是一个分布式服务框架
Dubbo 是一个分布式服务框架-----http://www.cnblogs.com/chanshuyi/p/5144288.html
- mybatis源码阅读-执行一个sql的流程(九)
图解 图片来源:https://my.oschina.net/zudajun/blog/670373 Mapper接口调用原理 我们整合成Spring 直接使用Mapper就能执行对应的sql 表现 ...
- - > 动规讲解基础讲解五——最长公共子序列问题
一些概念: (1)子序列: 一个序列A = a1,a2,……an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列. 例如: 对序列 1,3,5 ...
- SiteMesh2-sitemesh.xml的ParameterDecoratorMapper映射器的用法
继续使用上一章http://www.cnblogs.com/EasonJim/p/7086916.html的例子,改造成使用ParameterDecoratorMapper映射器的方法,这个映射器不需 ...
- spring boot日期转换
spring boot 作为微服务简易架构.拥有其自身的特点.快速搭建架构 简单 快捷.这里我只是简单的介绍下我遇到的其中的 两个问题.第一前台页面传递的时间类型 无法自动映射到Java的 Date ...
- iOS网络高级编程:iPhone和iPad的企业应用开发之错误处理
本章内容 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWluZ2h1YXdlbmthbmc=/font/5a6L5L2T/fontsize/400/fi ...
- Python&MySQL
环境:windows8+Python2.7+MySQL5.6 尝试过在C/C++中嵌入SQL语言,最终在其复杂"繁琐"环境配置中败下阵来,后来发现Python和MySQL比較eas ...
- CVPR2015一些文章整理
简单看了一部分CVPR2015的文章.整理了一下. 当中我决定把精彩的文章加粗. 主要是认为有些文章仅仅读了一遍,没有发现非常多非常有道理的point(虽然我承认他们的工作都花了非常大的功夫.可是没有 ...