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个线段,任意两个线段严格不相交,且每个线段不平行于坐标轴.移 ...
随机推荐
- python输出带颜色字体详解
在python开发的过程中,经常会遇到需要打印各种信息.海量的信息堆砌在控制台中,就会导致信息都混在一起,降低了重要信息的可读性.这时候,如果能给重要的信息加上字体颜色,那么就会更加方便用户阅读了. ...
- js之定时器操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python随笔day02
算术运算符 + - * ** / // % 比较运算符 > < == >= <= != Python中提供一种更加简单的比较方式. 当判断 ...
- intel compiler的表现
好久没弄这个东西,今天突然想试下,代码没写完,以后补. #include <stdio.h> #include <stdlib.h> #include <time.h&g ...
- wannafly-day1 Problem A - Birthday
思路:队友贪心WA了,然后就没有然后了,自己也是第一次接触最小费用流的题.借这个题来学习一下,利用Spfa每次来找到一个最短的路径同时保存路径,每一次寻找最短路径就将这条路的最小费用流给剪掉,然后继续 ...
- [COGS309] [USACO 3.2] 香甜的黄油
★★ 输入文件:butter.in 输出文件:butter.out 简单对比 时间限制:1 s 内存限制:128 MB 描述 农夫John发现做出全威斯康辛州最甜的黄油的方法:糖.把糖 ...
- [Usaco2016 Open]Diamond Collector
题目描述 Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her s ...
- oracle中的类似BIN$MrkCYT9eTTK+0sStMwn7+Q==$0的表的作用
https://www.2cto.com/database/201211/166482.html https://docs.oracle.com/cd/E11882_01/server.112/e40 ...
- Drools等规则引擎技术对比分析
项目中需要设计开发一个规则引擎服务,于是调研了业界常用的规则引擎. 常见的规则引擎如下: Ilog JRules 是最有名的商用BRMS: Drools 是最活跃的开源规则引擎: Jess 是Clip ...
- Android GIS开发系列-- 入门季(3) GraphicsLayer添加点、线、面
GraphicsLayer是图形图层,可以自定义图形添加到地图上.调用GraphicsLayer的addGraphic方法就能添加图形,此方法要一个Graphic对象,此对象的构造方法是Graphic ...