0% found this document useful (0 votes)
15 views4 pages

Message

The document contains a C++ implementation of a segment tree with lazy propagation for handling range updates and queries on an array. It allows for updating elements based on modular arithmetic and querying the number of pairs in a specified range. The main function handles input and output for the segment tree operations, including updates and queries based on user input.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views4 pages

Message

The document contains a C++ implementation of a segment tree with lazy propagation for handling range updates and queries on an array. It allows for updating elements based on modular arithmetic and querying the number of pairs in a specified range. The main function handles input and output for the segment tree operations, including updates and queries based on user input.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

#include <bits/stdc++.

h>
using namespace std;

#define ll long long


#define int ll

struct segtree{
vector<vector<int>> el;
vector<int> lazy;
int size;

segtree(int n){
size=1;
while(size<=n) size<<=1;
el.assign(2*size,{0,0,0});
lazy.assign(2*size,0);
}

void build(int v, int tl, int tr, vector<int> &a){


if(tl==tr){
if(a.size()<=tl) return;
el[v][a[tl]]=1;
return;
}
int tm=(tl+tr)/2;
build(2*v,tl,tm,a);
build(2*v+1,tm+1,tr,a);
el[v][0]=el[2*v][0]+el[2*v+1][0];
el[v][1]=el[2*v][1]+el[2*v+1][1];
el[v][2]=el[2*v][2]+el[2*v+1][2];
}

void build(vector<int> &a){


build(1,0,size-1,a);
}

void update(int v, int tl, int tr, int l, int r, int p){
if(lazy[v]){
if(lazy[v]==1) {
int temp=el[v][2];
el[v][2]=el[v][1];
el[v][1]=el[v][0];
el[v][0]=temp;
}
else{
int temp=el[v][2];
el[v][2]=el[v][0];
el[v][0]=el[v][1];
el[v][1]=temp;
}
if(tl!=tr){
lazy[2*v]=(lazy[2*v]+lazy[v])%3;
lazy[2*v+1]=(lazy[2*v+1]+lazy[v])%3;
}
lazy[v]=0;
}
if(tl>r||tr<l) return;
if(l<=tl&&tr<=r){
if(p==1) {
int temp=el[v][2];
el[v][2]=el[v][1];
el[v][1]=el[v][0];
el[v][0]=temp;
}
else{
int temp=el[v][2];
el[v][2]=el[v][0];
el[v][0]=el[v][1];
el[v][1]=temp;
}
if(tl!=tr){
lazy[2*v]=(lazy[2*v]+p)%3;
lazy[2*v+1]=(lazy[2*v+1]+p)%3;
}
return;
}
int tm=(tl+tr)/2;
update(2*v,tl,tm,l,r,p);
update(2*v+1,tm+1,tr,l,r,p);
el[v][0]=el[2*v][0]+el[2*v+1][0];
el[v][1]=el[2*v][1]+el[2*v+1][1];
el[v][2]=el[2*v][2]+el[2*v+1][2];
}

void update(int l, int r, int p){


update(1,0,size-1,l,r,p);
}

pair<int,pair<int,int>> query(int v, int tl, int tr, int l, int r){


if(lazy[v]){
if(lazy[v]==1) {
int temp=el[v][2];
el[v][2]=el[v][1];
el[v][1]=el[v][0];
el[v][0]=temp;
}
else{
int temp=el[v][2];
el[v][2]=el[v][0];
el[v][0]=el[v][1];
el[v][1]=temp;
}
if(tl!=tr){
lazy[2*v]=(lazy[2*v]+lazy[v])%3;
lazy[2*v+1]=(lazy[2*v+1]+lazy[v])%3;
}
lazy[v]=0;
}
if(tl>r||tr<l) return {0,{0,0}};
if(l<=tl&&tr<=r) return {el[v][0],{el[v][1],el[v][2]}};
int tm=(tl+tr)/2;
auto x=query(2*v,tl,tm,l,r);
auto y=query(2*v+1,tm+1,tr,l,r);
pair<int,pair<int,int>> z={x.first+y.first,
{x.second.first+y.second.first,x.second.second+y.second.second}};
return z;

}
vector<ll> query(int l, int r){
auto it=query(1,0,size-1,l,r);
vector<ll> x= {it.first, it.second.first, it.second.second};
return x;
}

};

signed main(){

ios_base::sync_with_stdio(0);
cin.tie(0);

int n,q;
cin>>n>>q;
vector<int> a(n);
vector<int> b(n);
segtree st(n);

for(int i=0;i<n;i++){
char p;
cin>>p;
int x=p-'0';
a[i]=x%3;
b[i]=x%3;
if(i) a[i]=(a[i]+a[i-1])%3;
}
st.build(a);

while(q--){
int x;
cin>>x;
if(x==1){
int y,z;
cin>>y>>z;
z%=3;
int curr=z;
z=(z-b[y-1]+3)%3;
b[y-1]=curr;
if(z) st.update(y-1,n-1,z);
}
else{

int l, r;
cin>>l>>r;
auto p=st.query(l-1,r-1);
ll ans=0;
if(l-1){
auto q=st.query(l-2,l-2);
for(int i=0;i<3;i++) p[i]+=q[i];
}
else p[0]++;
for(auto it:p) ans+=((it*(it-1))/2);

cout<<ans<<"\n";
}
}

You might also like