90分怎么卡常
查看原帖
90分怎么卡常
773841
Pop_Agoni楼主2024/8/15 20:13
#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的方法

2024/8/15 20:13
加载中...