CF627B Factory Repairs

CF627B Factory Repairs

考虑当前每个数的贡献,下面以 aa 举例。

  • 如果当前的 x>ax> a,那它对于答案的贡献就是 aa

  • 如果当前的 xax \le a,那它对答案的贡献就是 xx

不难发现,对于大于等于 aa 的数,他对答案的贡献与出现次数有关系。而对于小于 aa 的数,用数据结构维护它的和就好。

所以答案就出来了,我们只用维护大于等于 aa 的数的个数以及小于 aa 的数的和。

具体的实现方式看代码即可。直接在 tt 数组上改。然后根据我们的定义具体实现即可。

#include<bits/stdc++.h>
using namespace std;
const int INF=1e6+10;
#define int long long 
int t[INF<<1];
template <class T,const int N> class treeA{
	struct node{
		int sum,num;
	}Tree[N<<2];
	public:
		void updateSum(int l,int r,int s,int t,int p,int val){
			if(l<=s&&t<=r){
				Tree[p].sum+=val;
				return ;
			}
			int mid=(s+t)>>1;
			if(l<=mid)	updateSum(l,r,s,mid,p<<1,val);
			if(r>mid)	updateSum(l,r,mid+1,t,p<<1|1,val);
			Tree[p].sum=Tree[p<<1].sum+Tree[p<<1|1].sum;
		}
		void updateNum(int l,int r,int s,int t,int p){
			if(l<=s&&t<=r){
				Tree[p].num++;
				return ;
			}
			int mid=(s+t)>>1;
			if(l<=mid)	updateNum(l,r,s,mid,p<<1);
			if(r>mid)	updateNum(l,r,mid+1,t,p<<1|1);
			Tree[p].num=Tree[p<<1].num+Tree[p<<1|1].num;
		}
		T Querynum(int l,int r,int s,int t,int p){
			if(l<=s&&t<=r)	return Tree[p].num;
			int mid=(s+t)>>1,ans=0;
			if(l<=mid)	ans+=Querynum(l,r,s,mid,p<<1);
			if(r>mid)	ans+=Querynum(l,r,mid+1,t,p<<1|1);
			return ans;
		}
		T Querysum(int l,int r,int s,int t,int p){
			if(l<=s&&t<=r)	return Tree[p].sum;
			int mid=(s+t)>>1,ans=0;
			if(l<=mid)	ans+=Querysum(l,r,s,mid,p<<1);
			if(r>mid)	ans+=Querysum(l,r,mid+1,t,p<<1|1);
			return ans;
		}
		
};
signed main(){
	treeA<int,INF>TreeA,TreeB;
	int n,k,a,b,q;
	cin>>n>>k>>a>>b>>q;
	while(q--){
		int opt,x,y;
		cin>>opt;
		if(opt==1){
			cin>>x>>y;
			if(t[x]<a&&t[x]+y>a)	
				TreeA.updateSum(x,x,1,n,1,-t[x]),TreeA.updateNum(x,x,1,n,1);
			if(t[x]<b&&t[x]+y>b)	
				TreeB.updateSum(x,x,1,n,1,-t[x]),TreeB.updateNum(x,x,1,n,1);
			if(t[x]<a&&t[x]+y<a)	
				TreeA.updateSum(x,x,1,n,1,y);
			if(t[x]<b&&t[x]+y<b)	
				TreeB.updateSum(x,x,1,n,1,y);
			t[x]+=y;
			if(t[x]==a)	TreeA.updateSum(x,x,1,n,1,-t[x]),TreeA.updateNum(x,x,1,n,1);
			if(t[x]==b)	TreeB.updateSum(x,x,1,n,1,-t[x]),TreeB.updateNum(x,x,1,n,1);
		}
		else{
			cin>>x;
			int num1=0,Sum1=0,num2=0,Sum2=0;
			if(x-1>0)
				num1=TreeB.Querynum(1,x-1,1,n,1),Sum1=TreeB.Querysum(1,x-1,1,n,1);
			if(x+k<=n)
				num2=TreeA.Querynum(x+k,n,1,n,1),Sum2=TreeA.Querysum(x+k,n,1,n,1); 
			cout<<Sum1+Sum2+num1*b+num2*a<<endl;
//			cout<<Sum1<<" "<<Sum2<<" "<<num1<<" "<<num2<<endl;
		}
	}
}
//Sum: 比a,b小的数的和,num:比a,b的数值大于等于的数的个数
posted @   June_Failure  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示