CF1924 B

link

发现对于一个没有船的点 \(x_i\),代价是 \(V_l\times (r-x_i)\)

所以对于一段没有船的区间 \([L,R]\),代价是 \(\sum\limits_L^RV_l\times (r-x_i)\)

由于 \(V_l\)\(r\) 都是定值,所以可以变为 \(V_l\times (R-L+1)\times r-V_l\times\sum\limits_L^Rx_i\)

这个东西可以通过等差数列快速求出来,相当于我们可以快速求出来一段没有船的区间的代价。

所以我们想到用线段树来维护区间的代价。

如果要插入一艘船,设插入位置为 \(p\),插入之前最靠近 \(p\) 的船为 \(l\)\(r\),我们只需要修改三段区间:

  • \([l+1,x-1]\)

  • \([x+1,r-1]\)

  • \([x,x]\),将代价改为 \(0\)

至于找插入之前最靠近的船,可以用 set 来维护。

时间复杂度 \(O((m+q)\log n)\)


#include<bits/stdc++.h>

typedef long long LL;
//typedef int long long;
typedef std::pair<int,int> pii;

#define ok putstrln("OrzFinderHT")
#define int long long
//#define check_time printf("%.8f\n",clocks()/CLOCK_PER_SEC)

template<typename T>
void abs(T &N){
	if(N>=0) N=N;
	else N=-N;
}

namespace G_{
	template<typename T>
	inline void read(T &a){
		a=0;
		int f=1;
		char c=getchar();
		while(c<'0'||c>'9'){
			if(c=='-') f=-1;
			c=getchar();
		}
		while(c>='0'&&c<='9') a=a*10+(int)(c-'0'),c=getchar();
		a*=f;
	}
	inline void get_enter(){
		getchar();
	}
	inline void get_str(std::string &str){
		char c=getchar();
		while(c!=' '&&c!='\n') str+=c,c=getchar();
	}
	template<typename T>
	inline void putN(T N){
		char stk[70];
		short top=0;
		if(N<0) putchar('-'),abs(N);
		do{
			stk[++top]=N%10+48;
			N/=10;
		}while(N);
		while(top) putchar(stk[top--]);
	}
	template<typename T>
	inline void putsp(T N){
		putN(N);
		putchar(' ');
	}
	template<typename T>
	inline void putln(T N){
		putN(N);
		putchar('\n');
	}
	inline void putstr(std::string str){
		int sz=str.size()-1;
		for(int i=0;i<=sz;i++) putchar(str[i]);
	}
	inline void putstrln(std::string str){
		putstr(str);
		putchar('\n');
	}
	inline void Yes(){
		putstrln("Yes");
	}
	inline void No(){
		putstrln("No");
	}
}

//using namespace get_give;

using namespace G_;

const int maxn=3e5+10;

struct tree{
	LL l,r,ls,rs,lz,sum,vl,Rr;
}s[maxn*2];

int tot=0,n,m,q,X[maxn],V[maxn];

std::set<int>st;

int f(LL sx,LL wx,LL xs){
	return (sx+wx)*xs/2;
}

void push_up(int p){
	int ls=s[p].ls,rs=s[p].rs;
	s[p].sum=s[ls].sum+s[rs].sum;
}

int build(int l,int r){
	int p=++tot;
	s[p].l=l,s[p].r=r;
	if(l==r) return p;
	int mid=(l+r)>>1;
	s[p].ls=build(l,mid);
	s[p].rs=build(mid+1,r);
//	if(l==5&&r==8) printf("#####%lld\n",p);
//	if(p==17) printf("@@@@@%lld %lld\n",s[p].l,s[p].r);
	push_up(p);
	return p;
}

void push_down(int p){
	if(s[p].lz){
		LL ls=s[p].ls,rs=s[p].rs,vl=s[p].vl,Rr=s[p].Rr;
		s[ls].lz=s[rs].lz=1;
		s[p].lz=0;
		s[ls].sum=(s[ls].r-s[ls].l+1)*vl*Rr-vl*f(s[ls].l,s[ls].r,s[ls].r-s[ls].l+1);
		s[rs].sum=(s[rs].r-s[rs].l+1)*vl*Rr-vl*f(s[rs].l,s[rs].r,s[rs].r-s[rs].l+1);
//		if(p==16) ok;
		s[ls].vl=s[rs].vl=vl;
		s[ls].Rr=s[rs].Rr=Rr;
	}
	return ;
}

void update(int p,int L,int R,int vl,int Rr){
	int l=s[p].l,r=s[p].r;
	if(l>=L&&r<=R){
		s[p].lz=1;
		s[p].sum=(r-l+1)*vl*Rr-vl*f(l,r,r-l+1);
		s[p].vl=vl,s[p].Rr=Rr;
		return ;
	}
	push_down(p);
	int mid=(l+r)>>1;
	if(mid>=L) update(s[p].ls,L,R,vl,Rr);
	if(R>mid) update(s[p].rs,L,R,vl,Rr);
	push_up(p);
	return ;
}

int query(int p,int L,int R){
	int l=s[p].l,r=s[p].r;
	if(l>=L&&r<=R) return s[p].sum;
	push_down(p);
	int mid=(l+r)>>1,ret=0;
	if(mid>=L) ret+=query(s[p].ls,L,R);
	if(R>mid) ret+=query(s[p].rs,L,R);
	return ret;
}

signed main(){
//	std::ios::sync_with_stdio(false);
//	std::cin.tie(0);
	read(n),read(m),read(q);
	build(1,n);
	for(int i=1;i<=m;i++) {
		int loc;
		read(loc);
		st.insert(loc);
		X[i]=loc;
	}
//	std::sort(X+1,X+m+1);
	for(int i=1;i<=m;i++) read(V[X[i]]);
	std::sort(X+1,X+m+1);
	for(int i=1;i<m;i++) update(1,X[i]+1,X[i+1]-1,V[X[i]],X[i+1]);//,printf("%lld\n",query(1,2,7));
//	ok;
//	printf("%lld\n",query(1,3,8));
//	ok;
	int cnt=m;
	while(q--){
		int opt;
		read(opt);
		if(opt==1){
			int x,v;
			read(x),read(v);
			st.insert(x);
			auto it=st.lower_bound(x),l=it,r=it;
			l--,r++;
			int rn=*r,ln=*l;
			update(1,ln+1,x-1,V[ln],x);
			update(1,x+1,rn-1,v,rn);
			update(1,x,x,0,0);
			V[x]=v;
		}else {
			int l,r;
			read(l),read(r);
			printf("%lld\n",query(1,l,r));
		}
	}
	return 0;
}
/*
-读入字符一定检查回车
- 能不能搜索?
-函数要有返回值!
-想好了再写!
*/

/*
1000 3 1
1 1000 318
2704361 9570636 1106813
2
*/

posted @ 2024-01-30 14:52  BYR_KKK  阅读(27)  评论(0)    收藏  举报