QOJ 6504. CCPC Final 2022 D Flower's Land 2题解
QOJ 6504. CCPC Final 2022 D Flower's Land 2题解
题意简述
给你一个只含 \(0,1,2\) 的序列,相邻两个相同的数字可以直接消掉。
询问包含两种
区间所有数 \(+1\) 并对 \(3\) 取模。
求一段区间能否用上述消除方式消完。
样例输入
8 9
01211012
2 4 5
2 3 6
1 6 8
1 6 8
2 3 6
2 1 8
1 1 1
1 7 7
2 1 8
样例输出 #1
Yes
No
Yes
No
Yes
提示
在我们做相邻两个能被消掉,判断一段区间能否被消掉时,常常用矩阵来考虑。
把每一种颜色用一种矩阵来表示,若当前位是偶数就设为这个矩阵,若当前位是奇数就设为这个矩阵的逆。
求解就把所有的矩阵乘起来,看最后结果矩阵是不是 \(I\) 。
为什么矩阵是正确的呢?因为矩阵满足结合律但不满足交换律。
这样就可以保证 \(1,2,3,1,2,3\) 会判断为错。
如果还没理解,下面再解释详细一点:
这是一段序列 \(0122221000\) 显然他是合法的。
在矩阵中,因为满足结合律,你先算中间那段 \(2222\) ,因为奇数和偶数个数相同,一定为 \(I\) ,相当于没有了,变成了 \(0110000\) 。一直向下就可以得到 \(I\)。
题解
我们用线段树来维护矩阵乘法,这很容易,具体就是加了以后如何在矩阵中体现出来。
因为只有 \(0,1,2\) ,我们把当前,\(+1\) 后, \(+2\) 后的矩阵都记录下来。这样就可以了。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5 + 10, mod = 998244353;
int n,q;
char x;
int a[N], opt, l, r;
inline ll mpow(ll x,int k){
ll ans = 1;
while(k){
if(k & 1) ans = ans * x % mod;
x = x * x % mod;
k >>= 1;
}
return ans;
}
struct Mar{
ll a[3][3];
inline Mar operator *(const Mar b)const{
Mar c;
for(int i = 1; i <= 2; ++i){
for(int j = 1; j <= 2; ++j){
c.a[i][j] = 0;
for(int k = 1;k <= 2; ++k){
c.a[i][j] = (c.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
}
}
}
return c;
}
inline bool check(){
if(a[1][1] != 1) return 0;
if(a[1][2] != 0) return 0;
if(a[2][1] != 0) return 0;
if(a[2][2] != 1) return 0;
return 1;
}
inline Mar inv()const{
Mar c, b;
c.a[1][1] = 1;
c.a[1][2] = 0;
c.a[2][1] = 0;
c.a[2][2] = 1;
for(int i = 1; i <= 2; ++i)for(int j = 1; j <= 2; ++j) b.a[i][j] = a[i][j];
for(int i = 1; i <= 2; ++i){
for(int j = 1; j <= 2; ++j){
if(i == j) continue;
ll w = b.a[j][i] * mpow(b.a[i][i],mod - 2) % mod;
for(int k = 1; k <= 2; ++k){
b.a[j][k] = (b.a[j][k] - b.a[i][k] * w % mod + mod) % mod;
}
for(int k = 1; k <= 2; ++k){
c.a[j][k] = (c.a[j][k] - c.a[i][k] * w % mod + mod) % mod;
}
}
}
for(int i = 1; i <= 2; ++i){
for(int j = 1; j <= 2; ++j){
c.a[i][j] = c.a[i][j] * mpow(b.a[i][i],mod - 2) % mod;
}
}
return c;
}
inline void print(){
for(int i = 1; i <= 2; ++i){
for(int j = 1; j <= 2; ++j){
cout<<a[i][j]<<' ';
}
cout<<'\n';
}
}
}I;
struct node{
Mar now,nxt,nnt;
int tag;
}tr[N << 2];
Mar m[3], m_[3];
inline void pre(){
I.a[1][1] = 1,
I.a[1][2] = 0;
I.a[2][1] = 0;
I.a[2][2] = 1;
m[0].a[1][1] = 2,m[0].a[1][2] = 3;
m[0].a[2][1] = 5,m[0].a[2][2] = 7;
m[1].a[1][1] = 11,m[1].a[1][2] = 13;
m[1].a[2][1] = 17,m[1].a[2][2] = 19;
m[2].a[1][1] = 23,m[2].a[1][2] = 29;
m[2].a[2][1] = 31,m[2].a[2][2] = 37;
m_[0] = m[0].inv();
m_[1] = m[1].inv();
m_[2] = m[2].inv();
}
inline void input(){
cin>> n >> q;
for(int i = 1; i <= n; ++i){
cin>>x;
a[i] = x - '0';
}
}
inline void pd(int x){
cout<<"now:"<<'\n';
tr[x].now.print();
cout<<"nxt:"<<'\n';
tr[x].nxt.print();
cout<<"nnt:"<<'\n';
tr[x].nnt.print();
cout<<"tag:"<<'\n'<<tr[x].tag<<'\n';
}
inline void downdate(int x){
tr[x << 1].tag = (tr[x << 1].tag + tr[x].tag) % 3;
tr[x << 1 | 1].tag = (tr[x << 1 | 1].tag + tr[x].tag) % 3;
while(tr[x].tag > 0){
swap(tr[x << 1].now, tr[x << 1].nxt);
swap(tr[x << 1].nnt, tr[x << 1].nxt);
swap(tr[x << 1 | 1].now, tr[x << 1 | 1].nxt);
swap(tr[x << 1 | 1].nnt, tr[x << 1 | 1].nxt);
--tr[x].tag;
}
}
inline void pushup(int x){
tr[x].now = tr[x << 1].now * tr[x << 1 | 1].now;
tr[x].nxt = tr[x << 1].nxt * tr[x << 1 | 1].nxt;
tr[x].nnt = tr[x << 1].nnt * tr[x << 1 | 1].nnt;
}
inline void build(int x, int l, int r){
if(l == r){
if(l % 2){
tr[x].now = m_[a[l]];
tr[x].nxt = m_[(a[l] + 1) % 3];
tr[x].nnt = m_[(a[l] + 2) % 3];
}else{
tr[x].now = m[a[l]];
tr[x].nxt = m[(a[l] + 1) % 3];
tr[x].nnt = m[(a[l] + 2) % 3];
}
return ;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
pushup(x);
}
inline void adtr(int x){
tr[x].tag = (tr[x].tag + 1) % 3;
swap(tr[x].now, tr[x].nxt);
swap(tr[x].nnt, tr[x].nxt);
}
inline void add(int x, int l, int r, int L, int R){
if(L <= l && r <= R){
adtr(x);
return ;
}
downdate(x);
int mid = (l + r) >> 1;
if(L <= mid) add(x << 1, l, mid, L, R);
if(R > mid) add(x << 1 | 1, mid + 1, r, L, R);
pushup(x);
}
inline Mar query(int x, int l, int r, int L, int R){
if(L <= l && r <= R){
// cout<<x<<'\n';
// tr[x].now.print();
return tr[x].now;
}
downdate(x);
int mid = (l + r) >> 1;
Mar ans = I;
if(L <= mid) ans = ans * query(x << 1, l, mid, L, R);
if(R > mid) ans = ans * query(x << 1 | 1,mid + 1, r, L, R);
return ans;
}
inline void op(){
build(1,1,n);
for(int i = 1; i <= q; ++i){
cin>> opt >> l >> r;
if(opt == 1){
add(1, 1, n, l, r);
}else if(opt == 2){
if(query(1, 1, n, l, r).check()){
cout<<"Yes"<<'\n';
}else{
cout<<"No"<<'\n';
}
}
}
}
int main(){
cin.tie(0)->sync_with_stdio(false);
pre();
input();
op();
return 0;
}
QOJ 6504. CCPC Final 2022 D Flower's Land 2题解的更多相关文章
- 2018 ccpc final I. Cockroaches
I. Cockroaches time limit per test6. s memory limit per test256 MB inputstandard input outputstandar ...
- CCPC final Cockroaches
算法假了,我想的是通过枚举x,删除y的影响,这样答案第一个是没有任何问题的,但是第二个会算重复. 因为我枚举每一个x的时候,得到的y,而算另外一个x的时候,可能已经通过其他的点选到了这个点y这就有点麻 ...
- 2016-2017 National Taiwan University World Final Team Selection Contest (Codeforces Gym) 部分题解
D 考虑每个点被删除时其他点对它的贡献,然后发现要求出距离为1~k的点对有多少个. 树分治+FFT.分治时把所有点放一起做一遍FFT,然后减去把每棵子树单独做FFT求出来的值. 复杂度$nlog^ ...
- 2018 CCPC 桂林游记
TYPE: Onsite Contest NAME: 2018 - CCPC - Guilin PLAT: HUSTOJ TIME: 2018/10/28 09:00-14:00 CST LOCA: ...
- HDU-SupportOrNot训练实录
菜鸡队训练实录. 现场赛记录: 2016:[名称:奖项/排名] ZJPSC:Gold/1 CCPC中南邀请赛:Gold/1 ICPC Dalian:Gold/24 ICPC Beijing:Gold/ ...
- HDU-AcmKeHaoWanLe训练实录
菜鸡队训练实录. 现场赛记录:[名称:奖项/排名] 2017: ICPC Shenyang:Gold/3 CCPC Hangzhou:Gold/3 ICPC Beijing:Gold/13 CCPC ...
- Front Page
General Team FST stay night from ShanDong University 19 - 20 CCPC QinHuangDao Gold (4 th) IUPC YinCh ...
- 牛客暑假多校第五场A.gpa
一.题意 给出你的N门课程的考试成绩和所占的机电数目.允许你放弃K门课的成绩,要求你的平均学分绩最高能达到多少. Kanade selected n courses in the university ...
- ccpc 2018 final G - Pastoral Life in Stardew Valley
#include <iostream> #include<cstdio> #include<cstring> #include<queue> using ...
- 2017 China Collegiate Programming Contest Final (CCPC 2017)
题解右转队伍wiki https://acm.ecnu.edu.cn/wiki/index.php?title=2017_China_Collegiate_Programming_Contest_Fi ...
随机推荐
- golang 必会之 pprof 监控系列(5) —— cpu 占用率 统计原理
golang pprof 监控系列(5) -- cpu 占用率 统计原理 大家好,我是蓝胖子. 经过前面的几节对pprof的介绍,对pprof统计的原理算是掌握了七八十了,我们对memory,bloc ...
- [Pytorch框架] 4.1 Fine tuning 模型微调
文章目录 4.1 Fine tuning 模型微调 4.1.1 什么是微调 为什么要微调 迁移学习 Transfer Learning 二者关系 4.1.2 如何微调 4.1.3 注意事项 4.1.3 ...
- MySQL之主从复制搭建
文章目录 主从复制 主从搭建 配置主从复制的命令 测试 总结 主从复制 主从也叫做(AB复制),允许一个服务器从一个服务器数据库(主服务器)的数据复制到一个或者多个MySQL数据库服务器. 主从复制的 ...
- LeetCode 双周赛 103(2023/04/29)区间求和的树状数组经典应用
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,我是小彭. 这场周赛是 LeetCode 双周赛第 103 场,难得在五一假期第一天打周赛的人数也没 ...
- 民谣女神唱流行,基于AI人工智能so-vits库训练自己的音色模型(叶蓓/Python3.10)
流行天后孙燕姿的音色固然是极好的,但是目前全网都是她的声音复刻,听多了难免会有些审美疲劳,在网络上检索了一圈,还没有发现民谣歌手的音色模型,人就是这样,得不到的永远在骚动,本次我们自己构建训练集,来打 ...
- 2022-10-10:以下go语言代码输出什么?A:[1 2 3 0 1 2];B:死循环;C:[1 2 3 1 2 3];D:[1 2 3]。 package main import “fmt“
2022-10-10:以下go语言代码输出什么?A:[1 2 3 0 1 2]:B:死循环:C:[1 2 3 1 2 3]:D:[1 2 3]. package main import "f ...
- 2022-10-04:以下go语言代码输出什么?A:{123} main.T{x:123} B:{123} T{x:123} C:boo boo D:boo main.T{x:123}。 packag
2022-10-04:以下go语言代码输出什么?A:{123} main.T{x:123} B:{123} T{x:123} C:boo boo D:boo main.T{x:123}. packag ...
- 2020-12-10:i++是原子操作吗?为什么?
福哥答案2020-12-10: 不是原子操作.i++分为三个阶段:1.内存到寄存器.2.寄存器自增.3.写回内存.这三个阶段中间都可以被中断分离开.***[评论](https://user.qzone ...
- 2021-12-19:找到所有数组中消失的数字。 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums
2021-12-19:找到所有数组中消失的数字. 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内.请你找出所有在 [1, n] 范围内但没有出现在 nums ...
- vscode运行java输出至指定文件夹
一.前言 最近呢,需要用vscode编写一点小的java程序,也就是单java文件,但是呢,我发现coderunner运行java,一个java文件编译出一个class文件,这也太乱了!不符合我简约的 ...