Lpl and Energy-saving Lamps(线段树取数)

本文介绍了一种使用线段树进行高效区间更新的应用案例。通过维护每次被减小的数值,实现了快速查找和更新,特别适用于需要频繁进行区间操作的问题场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://nanti.jisuanke.com/t/30996

用线段树来维护每次被减小的数,又是一种新操作。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#define mem(a,x) memset(a,x,sizeof(a))
#define s1(x) scanf("%d",&x)
#define s2(x,y) scanf("%d%d",&x,&y)
#define s3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define s4(x,y,z,k) scanf("%d%d%d%d",&x,&y,&z,&k)
#define ff(a,n) for(int i = 0 ; i < n; i++) scanf("%d",a+i)
#define ls 2*rt
#define rs 2*rt+1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define ll long long
using namespace std;
typedef pair<int,int> pii;
//inline ll ask(int x){ll res=0;while(x)res+=c[x],x-=x&(-x);return res;}
//inline void add(int x,int d){while(x<=n)c[x]+=d,x+=x&(-x);}
//int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b);}
const ll inf = 0x3f3f3f3f;
const int mx = 1e5+10;

int p[mx<<2],ans[mx][2],que[mx];
int n,m;
int now = 1,re = 0,num;
void build(int rt, int L, int R){
	if(L == R){
		s1(p[rt]);
		return;
	} 
	int mid =(L+R)/2;
	build(lson);
	build(rson);
	p[rt] = min(p[ls],p[rs]);
} 

void update(int rt, int L, int R){
	if(L == R){
		re -= p[rt];
		p[rt] = inf;
		num++;
		return ; 
	}
	int mid = (L+R)/2;//lv=p[ls],rv=;
	if(p[ls] <= re){                 //这里写错了变量名 尴尬 
	//	 cout<<"jin"<<ls<<endl;
		 update(lson);
	}
	if(p[rs] <= re){
	//	cout<<"jin"<<rs<<endl;
		update(rson);
	}
	p[rt] = min(p[ls],p[rs]);
}
int main(){
	//	freopen("F:\\in.txt","r",stdin);
	//int T=10;	scanf("%d",&T);
	s2(n,m);
	build(1,1,n);
//	cout<<p[2]<<"++"<<p[3]<<endl;
	int q,mxe = -1;
	s1(q);
	for(int i = 0; i < q; i++){
		s1(que[i]);
		mxe=max(mxe,que[i]);
	}
	now = 1;re = 0;num=0;
	while(now <= mxe){
		
		if(num == n){
			ans[now][0]=num;
			ans[now][1]=re;
		} 
		else{
			re += m;
			update(1,1,n);
			//printf("now = %d num = %d re =%d\n",now,num,re);
			ans[now][0]=num;
			ans[now][1]=re;
		}
		now++;
	}
	for(int i = 0; i < q; i++){
		printf("%d %d\n",ans[que[i]][0],ans[que[i]][1]);
	}


	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blaze Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值