csp该题链接
debug了两天,最后参考了@Pujx的CCF-CSP认证考试 202312-4 宝藏 100分题解才勉强过的,讲解也看大佬的吧。附上个人基本照抄的代码。(不加优化指令和输入输出加速时间刚好1.5s,加上后优化到800ms+,主要是cin.tie(0)和cout.tie(0)的作用,内存在9MB左右)
#pragma GCC optimize(2,3,"Ofast","inline")
#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
#include<cmath>
using namespace std;
const int M=998244353;
int n,m,len;
struct Matx
{
int m[2][2]={{1,0},{0,1}};
friend Matx operator*(const Matx &a,const Matx &b)
{
Matx temp;
temp.m[0][0]=(1LL*a.m[0][0]*b.m[0][0]+1LL*a.m[0][1]*b.m[1][0])%M;
temp.m[0][1]=(1LL*a.m[0][0]*b.m[0][1]+1LL*a.m[0][1]*b.m[1][1])%M;
temp.m[1][0]=(1LL*a.m[1][0]*b.m[0][0]+1LL*a.m[1][1]*b.m[1][0])%M;
temp.m[1][1]=(1LL*a.m[1][0]*b.m[0][1]+1LL*a.m[1][1]*b.m[1][1])%M;
return temp;
}
friend istream& operator>>(istream &in,Matx &mx)
{
return in>>mx.m[0][0]>>mx.m[0][1]>>mx.m[1][0]>>mx.m[1][1];
}
friend ostream& operator<<(ostream &out,const Matx &mx)
{
return out<<mx.m[0][0]<<' '<<mx.m[0][1]<<' '<<mx.m[1][0]<<' '<<mx.m[1][1];
}
};
struct Order
{
int v;
Matx matl,matr;
friend istream& operator>>(istream &in,Order &od)
{
od.matl=od.matr=Matx();
in>>od.v;
if(od.v==1)
in>>od.matl;
else if(od.v==2)
in>>od.matr;
return in;
}
};
vector<Order> order;
struct Block
{
int l,r,neg,sz,id;
vector<Matx> suml,sumr;
static int idx;
Block()
{
id=idx++;
l=id*len; r=min(l+len,n);
build();
}
void build()
{
neg=0;
suml.clear(); sumr.clear();
vector<int> matx;
for(int i=l;i<r;i++)
{
if(order[i].v!=3) matx.push_back(i);
else if(matx.size()) matx.pop_back();
else neg++;
}
sz=matx.size();
suml.push_back(Matx()); sumr.push_back(Matx());
for(auto i:matx)
{
suml.push_back(order[i].matl*suml.back());
sumr.push_back(sumr.back()*order[i].matr);
}
}
};
int Block::idx=0;
vector<Block> block;
Matx query(int l,int r)
{
int bl=l/len,br=r/len;
if(bl==br)
{
vector<int> matx;
for(int i=l;i<=r;i++)
{
if(order[i].v!=3) matx.push_back(i);
else if(matx.size()) matx.pop_back();
}
Matx L,R;
for(auto i:matx)
{
L=order[i].matl*L;
R=R*order[i].matr;
}
return L*R;
}
else
{
int neg=0;
Matx L,R;
vector<int> matx;
for (int i=block[br].l;i<=r;i++)
{
if(order[i].v!=3) matx.push_back(i);
else if(matx.empty()) neg++;
else matx.pop_back();
}
for(auto i:matx)
{
L=order[i].matl*L;
R=R*order[i].matr;
}
for(int i=br-1;i>bl;i--)
{
if(neg>=block[i].sz)
neg=neg-block[i].sz+block[i].neg;
else
{
L=L*block[i].suml[block[i].sz-neg];
R=block[i].sumr[block[i].sz-neg]*R;
neg=block[i].neg;
}
}
matx.clear();
for(int i=l;i<block[bl].r;i++)
{
if(order[i].v!=3) matx.push_back(i);
else if(matx.size()) matx.pop_back();
}
while(neg&&!matx.empty()) neg--,matx.pop_back();
for(int i=matx.size()-1;i>=0;i--)
{
L=L*order[matx[i]].matl;
R=order[matx[i]].matr*R;
}
return L*R;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>n>>m;
len=sqrt(n);
for(int i=0;i<n;i++)
{
order.push_back(Order());
cin>>order.back();
}
for(int i=0;i<n;i+=len)
block.push_back(Block());
while(m--)
{
int v;
cin>>v;
if(v==1)
{
int i;
cin>>i;
cin>>order[--i];
block[i/len].build();
}
else
{
int l,r;
cin>>l>>r;
cout<<query(--l,--r)<<endl;
}
}
return 0;
}