test152

扫描线操作,线段树维护左端点的答案,这样查询就是单点查询。考虑修改,一个暴力的做法是枚举区间内的所有点,将其对应颜色的权值更改,这个东西的复杂度是对的,考虑枚举颜色段,这个的数量是 \(O(n)\) 的。枚举颜色段这一操作可以刻画成找到每个点下一个和它颜色不同的点,线段树简单维护区间覆盖。

注意还需要维护前面后面和它第一个不同颜色的点,所以看上去需要四棵线段树拿脚维护,我写了,1e5 2s。考虑维护的信息实际上差不多,放到一棵线段树上即可,这样只需要两棵线段树,能拿到 95 分,少开一点 ll 就能过了。

#include<bits/stdc++.h>
// #define int long long
#define ll long long
#define fi first
#define se second
#define pii std::pair<int,int>
#define vint std::vector<int>
#define vpair std::vector<pii>
#define debug(...) fprintf(stderr,##__VA_ARGS__)

template<typename T>
void read(T &x){
	x=0;
	int f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') x=x*10+(int)(c-'0'),c=getchar();
	x*=f;
}

std::stack<char>st;
template<typename T>
void print(T x){
	if(x==0) putchar('0');
	if(x<0) putchar('-'),x=-x;
	while(st.size()) st.pop();
	while(x) st.push((char)('0'+x%10)),x/=10;
	while(st.size()) putchar(st.top()),st.pop();
}

template<typename T>
void printsp(T x){
	print(x),putchar(' ');
}

template<typename T>
void println(T x){
	print(x),putchar('\n');
}

template<typename T,typename I>
bool chkmin(T &a,I b){
	if(a>b) return a=b,1;
	return 0;
}

template<typename T,typename I>
bool chkmax(T &a,I b){
	if(a<b) return a=b,1;
	return 0;
}

template<typename T,typename I>
void addedge(std::vector<I>*vec,T u,T v){
	vec[u].push_back(v);
}

template<typename T,typename I,typename K>
void addedge(std::vector<K>*vec,T u,T v,I w){
	vec[u].push_back({v,w});
}

template<typename T,typename I>
void addd(std::vector<I>*vec,T u,T v){
	addedge(vec,u,v),addedge(vec,v,u);
}

template<typename T,typename I,typename K>
void addd(std::vector<K>*vec,T u,T v,I w){
	addedge(vec,u,v,w),addedge(vec,v,u,w);
}

bool Mbe;

const ll inf=1e18,MOD1=998244353,MOD2=1e9+7;

const int maxn=5e5+10;

int l[maxn],r[maxn],n,m,v[maxn],ql[maxn],qr[maxn],q;

ll ans[maxn];

vint vec[maxn];

struct SegmentTree{
	int l[maxn*2],r[maxn*2],ls[maxn*2],rs[maxn*2];
	ll sum[maxn*2],lz[maxn*2];
	int tot;
	void clear(){
		tot=0;
	}
	void push_up(int p){
		sum[p]=sum[ls[p]]+sum[rs[p]];
	}
	int build(int L,int R){
		int p=++tot;
		l[p]=L,r[p]=R,lz[p]=0;
		if(L==R) return sum[p]=0,p;
		int mid=(L+R)>>1;
		ls[p]=build(L,mid),rs[p]=build(mid+1,R);
		push_up(p);
		return p;
	}
	void push_down(int p){
		sum[ls[p]]+=lz[p]*(r[ls[p]]-l[ls[p]]+1);
		sum[rs[p]]+=lz[p]*(r[rs[p]]-l[rs[p]]+1);
		lz[ls[p]]+=lz[p],lz[rs[p]]+=lz[p];
		lz[p]=0;
	}
	void update(int p,int L,int R,ll x){
		if(l[p]>=L&&r[p]<=R){
			sum[p]+=x*(r[p]-l[p]+1);
			lz[p]+=x;
			return ;
		}
		int mid=(l[p]+r[p])>>1;
		push_down(p);
		// int mid=(l[p]+r[p])>>1;
		if(mid>=L) update(ls[p],L,R,x);
		if(R>mid) update(rs[p],L,R,x);
		push_up(p);
	}
	ll query(int p,int L,int R){
		// debug("p=%lld [%lld %lld] [%lld %lld]\n",p,l[p],r[p],L,R);
		if(l[p]>=L&&r[p]<=R) return sum[p];
		push_down(p);
		int mid=(l[p]+r[p])>>1;
		ll res=0;
		if(mid>=L) res+=query(ls[p],L,R);
		if(R>mid) res+=query(rs[p],L,R);
		return res;
	}
}ds;

struct SegmentTree2{
	int l[maxn*2],r[maxn*2],ls[maxn*2],rs[maxn*2],tag1[maxn*2],tag2[maxn*2],tag3[maxn*2];
	int tot;
	void clear(){
		tot=0;
	}
	int build(int L,int R,int gt,int gt2,int gt3){
		int p=++tot;
		l[p]=L,r[p]=R;
		tag1[p]=tag2[p]=tag3[p]=-1;
		if(L==R) return tag1[p]=gt,tag2[p]=gt2,tag3[p]=gt3,p;
		int mid=(L+R)>>1;
		ls[p]=build(L,mid,gt,gt2,gt3),rs[p]=build(mid+1,R,gt,gt2,gt3);
		return p;
	}
	void push_down(int p){
		if(tag2[p]!=-1){
			tag2[ls[p]]=tag2[rs[p]]=tag2[p];
			tag2[p]=-1;
		}
		if(tag3[p]!=-1){
			tag3[ls[p]]=tag3[rs[p]]=tag3[p];
			tag3[p]=-1;
		}
		if(tag1[p]==-1) return ;
		tag1[ls[p]]=tag1[rs[p]]=tag1[p];
		tag1[p]=-1;
		return ;
	}
	inline void update(int p,int L,int R,int x1,int x2,int x3){
		if(l[p]>=L&&r[p]<=R){
			if(x1!=-1) tag1[p]=x1;
			if(x2!=-1) tag2[p]=x2;
			if(x3!=-1) tag3[p]=x3;
			return ;
		}
		push_down(p);
		int mid=(l[p]+r[p])>>1;
		if(mid>=L) update(ls[p],L,R,x1,x2,x3);
		if(R>mid) update(rs[p],L,R,x1,x2,x3);
		return ;
	}
	pii query12(int p,int x){
		if(l[p]==r[p]) return {tag1[p],tag2[p]};
		push_down(p);
		int mid=(l[p]+r[p])>>1;
		if(mid>=x) return query12(ls[p],x);
		else return query12(rs[p],x);
	}
	int query3(int p,int x){
		if(l[p]==r[p]) return tag3[p];
		push_down(p);
		int mid=(l[p]+r[p])>>1;
		if(mid>=x) return query3(ls[p],x);
		else return query3(rs[p],x);
	}
	int query1(int p,int x){
		if(l[p]==r[p]) return tag1[p];
		push_down(p);
		int mid=(l[p]+r[p])>>1;
		if(mid>=x) return query1(ls[p],x);
		else return query1(rs[p],x);
	}
	// inline int query(int p,int x){
	// 	if(l[p]==r[p]) return tag[p];
	// 	push_down(p);
	// 	int mid=(l[p]+r[p])>>1;
	// 	if(mid>=x) return query(ls[p],x);
	// 	else return query(rs[p],x);
	// }
	// int ep(int p,int L,int R,int x){
	// 	if(l[p]>=L&&r[p]<=R){
	// 		if(l[p]==r[p]) return tag[p]>=x?l[p]:inf;
	// 		if(tag)
	// 	}
	// 	if(l[p]==r[p])
	// 		if(tag[p]>=x&&l[p]>=L&&r[p]<=R) return l[p];
	// 		else return inf;

	// 	// if(tag[r[ls[p]]]>=x)
	// }
}ds2;

bool Men;

signed main(){
	// freopen("data.in","r",stdin),freopen("my.out","w",stdout);
	debug("%.6lfMB\n",(&Mbe-&Men)/1048576.0);
	read(n),read(m),read(q);
	for(int i=1;i<=n;i++) read(l[i]),read(r[i]),read(v[i]);
	for(int i=1;i<=q;i++) read(ql[i]),read(qr[i]),vec[qr[i]].push_back(i);
	ds.clear(),ds.build(1,n),ds2.clear(),ds2.build(1,m,m+1,0,0);
	pii res;
	for(int i=1;i<=n;i++){
		int pl=l[i],pr=r[i];
		int now=pl;
		while(now<=pr){
			// debug("i=%lld now=%lld\n",i,now);
			res=ds2.query12(1,now);
			int nxt=res.fi;
			chkmin(nxt,pr+1);
			int col=res.se;
			if(col==0){
				now=nxt;
				continue;
			}
			// debug("now=%lld nxt=%lld col=%lld\n",now,nxt,col);
			//1~col 这些左端点会减去 v[col]*(nxt-now+1) 的贡献
			ds.update(1,1,col,-1ll*v[col]*(nxt-now));
			now=nxt;
		}
		// debug("ok\n");
		ds.update(1,1,i,1ll*v[i]*(r[i]-l[i]+1));
		int er=ds2.query3(1,l[i]);
		// int pos=ds3.query(1,l[i]);
		// int el=1,er=l[i];
		// while(el<=er){
		// 	int mid=(el+er)>>1;
		// 	if(ds2.query(1,mid)>=l[i]) er=mid-1;
		// 	else el=mid+1;
		// }
		if(er+1<l[i]) ds2.update(1,er+1,l[i]-1,l[i],-1,-1);//,debug("er=%lld li=%lld\n",er,l[i]);
		int el=ds2.query1(1,r[i]);
		if(el-1>r[i]) ds2.update(1,r[i]+1,el-1,-1,-1,r[i]);
		ds2.update(1,l[i],r[i],r[i]+1,i,l[i]-1);
		// ds3.update(1,l[i],r[i],i),ds2.update(1,l[i],r[i],r[i]+1),ds4.update(1,l[i],r[i],l[i]-1);
		// debug("ok\n");
		for(int j:vec[i]) ans[j]=ds.query(1,ql[j],ql[j]);//,debug("ok\n");
	}
	for(int i=1;i<=q;i++) println(ans[i]);
	debug("%.6lfms\n",1e3*clock()/CLOCKS_PER_SEC);
}
posted @ 2025-02-07 20:54  BYR_KKK  阅读(18)  评论(0)    收藏  举报