线段树单点修改的应用

思路:对初始状态进行建树,然后这题就相当于查询第一个合法的位置,并且对其值进行修改,整个题目要求维护的是区间最大值,很显然可以使用线段树。

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;
const int N = 2e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<int, 3> ar;
int mod = 1e9+7;
const int maxv = 4e6 + 5;
#define endl "\n"

int a[N],cnt[N];

int n,m,k;

struct node
{
    int l,r,val;
    #define l(x) tr[x].l
    #define r(x) tr[x].r
    #define val(x) tr[x].val
}tr[N*4];

void update(int p)
{
    val(p)=max(val(p*2),val(p*2+1));
}

void build(int p,int l,int r)
{
    if(l==r){
        tr[p]={l,r,m};
        return ;
    }
    l(p)=l,r(p)=r;
    int mid=(l+r)/2;
    build(p*2,l,mid),build(p*2+1,mid+1,r);
    update(p);
}

void query(int p,int l,int r,int x)
{
    if(l(p)==r(p)){
        cnt[l(p)]++;
        cout<<l(p)<<endl;
        val(p)-=x;
        if(cnt[l(p)]==k) val(p)=0;
        return  ;
    }
    int mid=(l(p)+r(p))/2;
    if(val(p*2)>=x) query(p*2,l,r,x);
    else if(val(p*2+1)>=x) query(p*2+1,l,r,x);
    else{
        cout<<-1<<endl;
        return ;
    }
    update(p);
}


void solve()
{
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++) cin>>a[i],cnt[i]=0;
    build(1,1,n);
    for(int i=1;i<=n;i++){
        query(1,1,n,a[i]);
    }
    
} 


int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    t=1;
    cin>>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}
相关推荐
wzdark3 小时前
基于堆的优先队列实现原理与复杂度分析4
算法
彧azz5 小时前
图的存储结构详解:邻接矩阵的原理、实现与应用
开发语言·数据结构·学习·php
老王熬夜敲代码5 小时前
BLAKE3:最快的密码学哈希函数
算法·密码学·哈希算法
hansang_IR5 小时前
【题解】P4460 [CQOI2018] 解锁屏幕
c++·算法
见闻小天地6 小时前
简博斯JG-C系列彩色激光同轴位移计:摄像头模组对位与行程测量的技术价值观察
人工智能·算法
ChampaignWolf6 小时前
在 SAP S/4HANA 内部基于 ICF Handler 从零实现 ABAP MCP Server:架构、代码与踩坑实录
c++·架构·sap·abap·mcp
葫三生6 小时前
《论三生原理》神话学构想与“神话历史”理论、《古史中的神话》思路异同?
大数据·人工智能·科技·深度学习·算法
liliangcsdn7 小时前
因子分析指标概念与示例
算法·机器学习
尘客-追梦7 小时前
Day 01:插件化之前,先看清 ABI 这堵墙
开发语言·c++·qt
SupL!8 小时前
LoftQ原理
算法