题意:

思路:因为线段树上每一段的矩阵之积只有两种,预处理一下,翻转的时候下传tag然后把另一种可能性换上来就好

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 200010
//#define M 200010
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const ll MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int dx[]={-,,,};
int dy[]={,,-,}; struct Ma
{
int n=,m=;
ll a[][];
void init()
{
n=m=;
mem(a,);
}
Ma operator +(Ma b) const
{
Ma c;
c.n=n; c.m=m;
rep(i,,n-)
rep(j,,m-) c.a[i][j]=a[i][j]+b.a[i][j];
return c;
}
Ma operator *(Ma b) const
{
Ma c;
c.init();
c.n=n; c.m=b.m;
rep(i,,n-)
rep(j,,b.m-)
rep(k,,m-) c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%MOD)%MOD;
return c;
}
}; Ma t[N<<][],M[],one,ans;
int b[N],tag[N];
char s[N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-, c=getchar();
return v*f;
} void pushdown(int p)
{
if(tag[p])
{
swap(t[ls][],t[ls][]);
swap(t[rs][],t[rs][]);
tag[ls]^=;
tag[rs]^=;
tag[p]=;
}
} void pushup(int p)
{
t[p][]=t[ls][]*t[rs][];
t[p][]=t[ls][]*t[rs][];
} void build(int l,int r,int p)
{
if(l==r)
{
t[p][]=M[b[l]];
t[p][]=M[b[l]^];
tag[p]=;
return;
}
int mid=(l+r)>>;
build(l,mid,ls);
build(mid+,r,rs);
pushup(p); } void update(int l,int r,int x,int y,int p)
{
if(x<=l&&r<=y)
{
tag[p]^=;
swap(t[p][],t[p][]);
return;
}
pushdown(p);
int mid=(l+r)>>;
if(x<=mid) update(l,mid,x,y,ls);
if(y>mid) update(mid+,r,x,y,rs);
pushup(p);
} Ma query(int l,int r,int x,int y,int p)
{
if(x<=l&&r<=y) return t[p][];
pushdown(p);
int mid=(l+r)>>;
Ma res=one;
if(x<=mid) res=res*query(l,mid,x,y,ls);
if(y>mid) res=res*query(mid+,r,x,y,rs);
return res;
} int main()
{
//freopen("1.in","r",stdin);
int n=read(),q=read();
scanf("%s",s+);
rep(i,,n) b[i]=s[i]-'A';
M[].n=M[].m=M[].n=M[].m=one.n=one.m=ans.n=ans.m=;
M[].a[][]=M[].a[][]=M[].a[][]=;
M[].a[][]=M[].a[][]=M[].a[][]=;
one.a[][]=one.a[][]=;
build(,n,); while(q--)
{
int op=read();
if(op==)
{
int x=read(),y=read();
update(,n,x,y,);
}
else
{
int x=read(),y=read(),A=read(),B=read();
Ma t=query(,n,x,y,);
// printf("t=\n");
//rep(i,0,1)
//{
// rep(j,0,1) printf("%I64d ",t.a[i][j]);
// printf("\n");
//}
ans.a[][]=A;
ans.a[][]=B;
ans.a[][]=ans.a[][]=;
ans=ans*t;
printf("%I64d %I64d\n",ans.a[][],ans.a[][]);
}
}
return ;
}

【CF1252K】Addition Robot(线段树,矩阵乘法)的更多相关文章

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

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

  2. hdu 5068(线段树+矩阵乘法)

    矩阵乘法来进行所有路径的运算, 线段树来查询修改. 关键还是矩阵乘法的结合律. Harry And Math Teacher Time Limit: 5000/3000 MS (Java/Others ...

  3. 【对不同形式矩阵的总结】WC 2009 最短路径问题(线段树+矩阵乘法)

    题意 ​ 题目链接:https://www.luogu.org/problem/P4150 ​ 一个 \(6\times n\) 的网格图,每个格点有一个初始权值.有两种操作: 修改一个格子的权值 求 ...

  4. MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)

    题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...

  5. CF718C Sasha and Array 线段树 + 矩阵乘法

    有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$   直接求不好求,改成矩阵乘法的形式:  $a_{i}=M^x\times ...

  6. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门  Portal  原题目描述在最下面.  简单的 ...

  7. LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

    线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...

  8. HDU 5068 Harry And Math Teacher 线段树+矩阵乘法

    题意: 一栋楼有n层,每一层有2个门,每层的两个门和下一层之间的两个门之间各有一条路(共4条). 有两种操作: 0 x y : 输出第x层到第y层的路径数量. 1 x y z : 改变第x层 的 y门 ...

  9. [tsA1490][2013中国国家集训队第二次作业]osu![概率dp+线段树+矩阵乘法]

    这样的题解只能舔题解了,,,qaq 清橙资料里有.. #include <iostream> #include <cstdio> #include <cstdlib> ...

  10. SP1716 GSS3(线段树+矩阵乘法)

    Code: #include <bits/stdc++.h> #define N 50001 #define ll long long #define lson now<<1 ...

随机推荐

  1. python每日一练:0012题

    第 0012 题: 敏感词文本文件 filtered_words.txt,里面的内容 和 0011题一样,当用户输入敏感词语,则用 星号 * 替换,例如当用户输入「北京是个好城市」,则变成「**是个好 ...

  2. java基础/数据加解密(Mooc)

    一.消息摘要算法 常用摘要算法: 以下 (HEX)内容:bc指Bouncy Castle  |  cc指:Apache commons Codec 1.消息摘要算法MD5及MD族(MD2,MD4) 消 ...

  3. MySQL数据库的连接池问题

    3. sqlalchemy设置连接池数量上限设置 SQLALCHEMY_POOL_SIZE = 100 SQLALCHEMY_MAX_OVERFLOW = 0 # 超出连接池数量的连接后,最多可以连接 ...

  4. python学习-第四天补充-面向对象

    python学习-第四天补充-面向对象 python 私有 --name mangling(名字修改.名字) 在命名时,通过使用两个下划线作为开头,可以使得这个变量或者函数编程私有的,但是这个其实的p ...

  5. tarjan算法应用 割点 桥 双连通分量

    tarjan算法的应用. 还需多练习--.遇上题目还是容易傻住 对于tarjan算法中使用到的Dfn和Low数组. low[u]:=min(low[u],dfn[v])--(u,v)为后向边,v不是u ...

  6. 洛谷 P1484 种树(优先队列,贪心,链表)

    传送门 解题思路 第一眼的贪心策略:每次都选最大的. 但是——不正确! 因为选了第i个树,第i-1和i-1棵树就不能选了.所以,要有一个反悔操作. 选了第i个后,我们就把a[i]的值更新为a[l[i] ...

  7. Codeforces 1262E Arson In Berland Forest(二维前缀和+二维差分+二分)

     题意是需要求最大的扩散时间,最后输出的是一开始的火源点,那么我们比较容易想到的是二分找最大值,但是我们在这满足这样的点的时候可以发现,在当前扩散时间k下,以这个点为中心的(2k+1)2的正方形块内必 ...

  8. 并查集专题: HDU1232畅通工程

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. TApplication,TForm,TControl,TComponent,TWinControl研究(博客索引)good

    TApplication,TForm,TControl,TComponent,TWinControl研究 http://blog.csdn.net/suiyunonghen/article/detai ...

  10. offsetWidth clientWidth scrollWidth 的区别

    了解 offsetWidth clientWidth scrollWidth 的区别 最近需要清除区分开元素的width,height及相应的坐标等,当前这篇用来区分offsetWidth clien ...