#include<bits/stdc++.h>
#define ll long long
#define int1 unsigned int
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
using namespace std;
int1 n,m,q;
int1 l,r,x[1000005],tim[1000005];
int1 tot[1000005];
ll ans[1000005];
int1 r1;
struct node{
int1 l,r,id;
}a[1000005];
int1 tr[4000005],lz[4000005];
ll fuck[4000005],mpc[4000005];
inline int1 read(){
int1 x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
inline void write(ll X)
{
if(X<0) {X=~(X-1); putchar('-');}
if(X>9) write(X/10);
putchar(X%10+'0');
}
bool cmp(node l,node r){
return l.r<r.r;
}
void pushdown(int1 x){
if(lz[x]){
lz[ls(x)]=lz[x];
lz[rs(x)]=lz[x];
tr[ls(x)]=lz[x];
tr[rs(x)]=lz[x];
lz[x]=0;
}
}
int1 query(int1 x,int1 l,int1 r,int1 T){
if(l==r) return tr[x];
if(lz[x]) pushdown(x);
int1 mid=(l+r)>>1;
if(T<=mid) return query(ls(x),l,mid,T);
else return query(rs(x),mid+1,r,T);
}
void update(int1 x,int1 l,int1 r,int1 L,int1 R,int1 res){
if(l>R||r<L) return;
if(L<=l&&r<=R){
tr[x]=res;
lz[x]=res;
return;
}
if(lz[x]) pushdown(x);
int1 mid=(l+r)>>1;
if(L<=mid) update(ls(x),l,mid,L,R,res);
if(R>mid) update(rs(x),mid+1,r,L,R,res);
}
void pushup(int1 x){
fuck[x]=fuck[ls(x)]+fuck[rs(x)];
}
void pushdown_1(int1 x,int1 l,int1 r){
if(mpc[x]){
mpc[ls(x)]+=mpc[x];
mpc[rs(x)]+=mpc[x];
ll mid=(l+r)>>1;
fuck[ls(x)]+=mpc[x]*(mid-l+1);
fuck[rs(x)]+=mpc[x]*(r-mid);
mpc[x]=0;
}
}
void update_1(int1 x,int1 l,int1 r,int1 L,int1 R,int1 res){
if(l>R||r<L) return;
if(L<=l&&r<=R){
fuck[x]+=res*(r-l+1);
mpc[x]+=res;
return;
}
if(mpc[x]) pushdown_1(x,l,r);
int1 mid=(l+r)>>1;
if(L<=mid) update_1(ls(x),l,mid,L,R,res);
if(R>mid) update_1(rs(x),mid+1,r,L,R,res);
pushup(x);
}
ll query_1(int1 x,int1 l,int1 r,int1 L,int1 R){
if(l>R||r<L) return 0;
if(L<=l&&r<=R){
return fuck[x];
}
if(mpc[x]) pushdown_1(x,l,r);
int1 mid=(l+r)>>1;
ll sum=0;
if(L<=mid) sum+=query_1(ls(x),l,mid,L,R);
if(R>mid) sum+=query_1(rs(x),mid+1,r,L,R);
return sum;
}
int main(){
n=read(),m=read(),q=read();
for(int i=1;i<=m;i++){
tot[i]=read();
if(tot[i]==1){
l=read(),r=read();
ll u=query(1,1,n,l);
ll v=query(1,1,n,r);
update(1,1,n,l,l,v);
update(1,1,n,r,r,u);
}
if(tot[i]==2){
l=read(),r=read(),x[i]=read();
update(1,1,n,l,r,i);
}
if(tot[i]==3){
x[i]=read();
tim[i]=query(1,1,n,x[i]);
}
}
for(int i=1;i<=q;i++){
a[i].l=read(),a[i].r=read();
a[i].id=i;
}
sort(a+1,a+q+1,cmp);
r1=0;
for(int i=1;i<=q;i++){
while(r1<a[i].r){
r1++;
if(tot[r1]==3&&tim[r1]){
update_1(1,1,m,tim[r1],tim[r1],x[tim[r1]]);
}
}
ans[a[i].id]=query_1(1,1,m,a[i].l,a[i].r);
}
for(int i=1;i<=q;i++){
write(ans[i]);
putchar('\n');
}
return 0;
}
打了两棵线段树 多次卡常,最少只T了一个点 有没有不改树状数组,通过卡常能改A的方法