前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「CSP-J/S2022模拟赛7.8 D」平凡的我

「CSP-J/S2022模拟赛7.8 D」平凡的我

作者头像
yzxoi
发布2022-09-19 14:10:27
4050
发布2022-09-19 14:10:27
举报
文章被收录于专栏:OI

「CSP-J/S2022模拟赛7.8 D」平凡的我

给定一个长度为 N 的数组 AQ 次操作:

  1. 单点修改 A_p = v
  2. 查询 a[l] + a[l+1] + \cdots a[r] 的历史最小值。

N,Q\leq 1.2\times 10^5

Tutorial(K-D Tree / 四分树)

考虑建立以 l,r 为两轴的平面以维护答案。

查询即为查询该平面上的一点的权值。

修改操作即修改满足 l\leq p \leq r 的所有 [l,r] 点的权值,显然这是一个矩形。

那么我们就变成了矩阵修改,单点查询问题。

每个点维护当前值以及最小值,用 K-D Tree / 四分树 维护即可。

时间复杂度:O(N\sqrt N)

Tutorial(莫队 + 线段树)

把所有操作离线。

考虑每个操作添加“时间戳”关键字。

那么我们用莫队维护出当前区间 [l,r],在线段树上以时间戳为下标,维护前缀和的最小值。

这个可以化为区间修改,区间查询,不难做到。

可以调调块长,把 \log 丢到根号里,可以做到。

时间复杂度 O(N\sqrt{N\log N})

但由于其巨大的常数,跑起来比 K-D Tree 慢很多。

但四分树由于其丑陋的结构,甚至无法足以通过本题。

Solution(莫队 + 线段树)

代码语言:javascript
复制
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define W while
#define I inline
#define RI register int
#define LL long long
#define Cn const
#define CI Cn int&
using namespace std;
namespace Debug{
	Tp I void _debug(Cn char* f,Ty t){cerr<<f<<'='<<t<<endl;}
	Ts I void _debug(Cn char* f,Ty x,Ar... y){W(*f!=',') cerr<<*f++;cerr<<'='<<x<<",";_debug(f+1,y...);}
	Tp ostream& operator<<(ostream& os,Cn vector<Ty>& V){os<<"[";for(Cn auto& vv:V) os<<vv<<",";os<<"]";return os;}
	#define gdb(...) _debug(#__VA_ARGS__,__VA_ARGS__)
}using namespace Debug;
namespace FastIO{
	#define FS 100000
	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
	int OT;char oc,FI[FS],FO[FS],OS[FS],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
	Tp I void writeln(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc('\n');}
}using namespace FastIO;
Cn int N=1.2e5+10,M=N;
int n,Qt,a[N],rt,bl[N],cnt;LL s[N],Ans[N];
struct Que{int l,r,id;}q[N];
class SegmentTree{
	private:
		LL T[N<<2],tg[N<<2];
		#define mid (l+r>>1)
		#define PT CI x=1,CI l=1,CI r=Qt
		#define LT x<<1,l,mid
		#define RT x<<1|1,mid+1,r
		#define PU(x) (T[x]=min(T[x<<1],T[x<<1|1]))
		#define AP(x,v) (T[x]+=v,tg[x]+=v)
		I void PD(CI x){tg[x]&&(AP(x<<1,tg[x]),AP(x<<1|1,tg[x]),tg[x]=0);}
	public:
		I void U(CI L,CI R,LL v,PT){
			if(L<=l&&r<=R) return AP(x,v),void();
			PD(x),L<=mid&&(U(L,R,v,LT),0),R>mid&&(U(L,R,v,RT),0),PU(x);
		}
		I LL Q(CI L,CI R,PT){
			if(L<=l&&r<=R) return T[x];
			LL X=0;return PD(x),L<=mid&&(X=min(X,Q(L,R,LT))),R>mid&&(X=min(X,Q(L,R,RT))),X;
		}
}T;
#define pa pair<int,int>
#define mp make_pair
#define fi first
#define se second
vector<pa> v[N];
#define pb push_back
I void add(CI x){
	for(auto i:v[x]) /*gdb(i.se,i.fi),*/T.U(i.se,n,i.fi);
}
I void del(CI x){
	for(auto i:v[x]) /*gdb(i.se,-i.fi),*/T.U(i.se,n,-i.fi);
}
int main(){
	RI i,o,l,r,S;for(read(n,Qt),S=sqrt(n*6),gdb(S),i=1;i<=n;i++) read(a[i]),s[i]=s[i-1]+a[i];for(i=1;i<=Qt;i++)
		read(o,l,r),o&1?v[l].pb(mp(r-a[l],i)),a[l]=r:(q[++cnt]={l,r,i},0);
	for(i=1;i<=n;i++) bl[i]=(i-1)/S+1;memset(Ans,-1,sizeof(Ans));
	for(sort(q+1,q+cnt+1,[&](Cn Que& x,Cn Que& y){return bl[x.l]^bl[y.l]?x.l<y.l:bl[x.l]&1?x.r<y.r:x.r>y.r;}),l=1,r=0,i=1;i<=cnt;i++){
		W(l>q[i].l) add(--l);W(r<q[i].r) add(++r);W(l<q[i].l) del(l++);W(r>q[i].r) del(r--);
		// cerr<<"Q "<<q[i].id<<" "<<T.Q(1,q[i].id)<<endl;
		Ans[q[i].id]=min(T.Q(1,q[i].id),0LL)+s[q[i].r]-s[q[i].l-1];
	}for(i=1;i<=Qt;i++) ~Ans[i]&&(writeln(Ans[i]),0);
	return clear(),cerr<<clock()<<"ms\n",0;
}

Solution(四分树)

代码语言:javascript
复制
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define W while
#define I inline
#define RI register int
#define LL long long
#define Cn const
#define CI Cn int&
using namespace std;
namespace Debug{
	Tp I void _debug(Cn char* f,Ty t){cerr<<f<<'='<<t<<endl;}
	Ts I void _debug(Cn char* f,Ty x,Ar... y){W(*f!=',') cerr<<*f++;cerr<<'='<<x<<",";_debug(f+1,y...);}
	Tp ostream& operator<<(ostream& os,Cn vector<Ty>& V){os<<"[";for(Cn auto& vv:V) os<<vv<<",";os<<"]";return os;}
	#define gdb(...) _debug(#__VA_ARGS__,__VA_ARGS__)
}using namespace Debug;
namespace FastIO{
	#define FS 100000
	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
	int OT;char oc,FI[FS],FO[FS],OS[FS],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
	Tp I void writeln(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc('\n');}
}using namespace FastIO;
Cn int N=1.2e5+10,M=N;
int n,Q,a[N],rt;LL s[N];
struct Que{int o,l,r,id;}q[N];
class SegmentTree{
	private:
		int cnt;
		struct node{int son[4];LL S,T,A;}T[M*40];
		#define midX (a+c>>1)
		#define midY (b+d>>1)
		#define S0 T[x].son[0],a,b,midX,midY
		#define S1 T[x].son[1],midX+1,b,c,midY
		#define S2 T[x].son[2],a,midY+1,midX,d
		#define S3 T[x].son[3],midX+1,midY+1,c,d
		#define PU(x) (T[x].S=T[T[x].son[0]].S+T[T[x].son[1]].S+T[T[x].son[2]].S+T[T[x].son[3]].S)
		I void PD(CI x){
			T[x].T&&(
			T[x].son[0]&&(T[x].T>0&&T[T[x].son[0]].T<0&&(PD(T[x].son[0]),0),T[T[x].son[0]].S+=T[x].T,T[T[x].son[0]].T+=T[x].T,T[T[x].son[0]].A=min(T[T[x].son[0]].A,T[T[x].son[0]].S),0),
			T[x].son[1]&&(T[x].T>0&&T[T[x].son[1]].T<0&&(PD(T[x].son[1]),0),T[T[x].son[1]].S+=T[x].T,T[T[x].son[1]].T+=T[x].T,T[T[x].son[1]].A=min(T[T[x].son[1]].A,T[T[x].son[1]].S),0),
			T[x].son[2]&&(T[x].T>0&&T[T[x].son[2]].T<0&&(PD(T[x].son[2]),0),T[T[x].son[2]].S+=T[x].T,T[T[x].son[2]].T+=T[x].T,T[T[x].son[2]].A=min(T[T[x].son[2]].A,T[T[x].son[2]].S),0),
			T[x].son[3]&&(T[x].T>0&&T[T[x].son[3]].T<0&&(PD(T[x].son[3]),0),T[T[x].son[3]].S+=T[x].T,T[T[x].son[3]].T+=T[x].T,T[T[x].son[3]].A=min(T[T[x].son[3]].A,T[T[x].son[3]].S),0),
			T[x].T=0);
		}
	public:
		I void B(int &x,CI a,CI b,CI c,CI d,CI Qa,CI Qb,CI Qc,CI Qd){
			!x&&(x=++cnt);if(Qa<=a&&Qb<=b&&c<=Qc&&d<=Qd) return ;
			Qa<=midX&&Qb<=midY&&(B(S0,Qa,Qb,min(Qc,midX),min(Qd,midY)),0),
			Qc>midX&&Qb<=midY&&(B(S1,max(Qa,midX+1),Qb,Qc,min(Qd,midY)),0),
			Qa<=midX&&Qd>midY&&(B(S2,Qa,max(Qb,midY+1),min(Qc,midX),Qd),0),
			Qc>midX&&Qd>midY&&(B(S3,max(Qa,midX+1),max(Qb,midY+1),Qc,Qd),0);
		}
		I void U(int& x,CI a,CI b,CI c,CI d,CI Qa,CI Qb,CI Qc,CI Qd,LL v){
			if(!x) return ;if(Qa<=a&&Qb<=b&&c<=Qc&&d<=Qd) return T[x].T<0&&v>0&&(PD(x),0),T[x].S+=v,T[x].T+=v,T[x].A=min(T[x].A,T[x].S),void();
			PD(x),Qa<=midX&&Qb<=midY&&(U(S0,Qa,Qb,min(Qc,midX),min(Qd,midY),v),0),
			Qc>midX&&Qb<=midY&&(U(S1,max(Qa,midX+1),Qb,Qc,min(Qd,midY),v),0),
			Qa<=midX&&Qd>midY&&(U(S2,Qa,max(Qb,midY+1),min(Qc,midX),Qd,v),0),
			Qc>midX&&Qd>midY&&(U(S3,max(Qa,midX+1),max(Qb,midY+1),Qc,Qd,v),0),PU(x);
		}
		I LL Q(int &x,CI a,CI b,CI c,CI d,CI Qa,CI Qb,CI Qc,CI Qd){
			if(Qa<=a&&Qb<=b&&c<=Qc&&d<=Qd) return T[x].A;
			LL S=0;return PD(x),Qa<=midX&&Qb<=midY&&(S+=Q(S0,Qa,Qb,min(Qc,midX),min(Qd,midY))),
			Qc>midX&&Qb<=midY&&(S+=Q(S1,max(Qa,midX+1),Qb,Qc,min(Qd,midY))),
			Qa<=midX&&Qd>midY&&(S+=Q(S2,Qa,max(Qb,midY+1),min(Qc,midX),Qd)),
			Qc>midX&&Qd>midY&&(S+=Q(S3,max(Qa,midX+1),max(Qb,midY+1),Qc,Qd)),S;
		}
}S;
int main(){
	RI i,o,l,r;for(read(n,Q),i=1;i<=n;i++) read(a[i]),s[i]=s[i-1]+a[i];for(i=1;i<=Q;i++) read(q[i].o,q[i].l,q[i].r);
	for(i=1;i<=Q;i++) !(q[i].o&1)&&(S.B(rt,1,1,n,n,q[i].l,q[i].r,q[i].l,q[i].r),0);
	for(i=1;i<=Q;i++) q[i].o&1?(S.U(rt,1,1,n,n,1,q[i].l,q[i].l,n,q[i].r-a[q[i].l]),a[q[i].l]=q[i].r,0):(writeln(s[q[i].r]-s[q[i].l-1]+S.Q(rt,1,1,n,n,q[i].l,q[i].r,q[i].l,q[i].r)),0);
	return clear(),0;
},0);
	return clear(),cerr<<clock()<<"ms\n",0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 「CSP-J/S2022模拟赛7.8 D」平凡的我
    • Tutorial(K-D Tree / 四分树)
      • Tutorial(莫队 + 线段树)
        • Solution(莫队 + 线段树)
          • Solution(四分树)
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档