2019杭电多校第三场 6606-Distribution of books(树状数组)

探讨了一个图书分配问题,目标是最小化同学间快乐的最大值。通过二分查找和树状数组,解决寻找最长下降子序列的挑战。

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

Problem Description
传送门
zz6d likes reading very much, so he bought a lot of books. One day, zz6d brought n books to a classroom in school. The books of zz6d is so popular that K students in the classroom want to borrow his books to read. Every book of zz6d has a number i (1<=i<=n). Every student in the classroom wants to get a continuous number books. Every book has a pleasure value, which can be 0 or even negative (causing discomfort). Now zz6d needs to distribute these books to K students. The pleasure value of each student is defined as the sum of the pleasure values of all the books he obtains.Zz6d didn’t want his classmates to be too happy, so he wanted to minimize the maximum pleasure of the K classmates. zz6d can hide some last numbered books and not distribute them,which means he can just split the first x books into k parts and ignore the rest books, every part is consecutive and no two parts intersect with each other.However,every classmate must get at least one book.Now he wonders how small can the maximum pleasure of the K classmates be.

1<=T<=10
1<=n<=2*105
1<=k<=n
-109<=ai<=109

Input
Input contains multiple test cases.
The first line of the input is a single integer T which is the number of test cases. T test cases follow.
For each test case, the first line contains two integer n,k: the number of books and the number of his classmates. The second line contains n integers a1 ,a2,…, an−1,an. (aimeans the pleasure value of book i.)∑n<=2*105.

Output
For each case, print the smallest maximum pleasure of the K classmates, and one line one case.

Sample Input
2
4 2
3 -2 4 -2
5 4
-1 -1 -1 -1 6

Sample Output
2
-1
Hint
In the first example,classmate 1 get book 1,2, classmate 2 get book 3,4.the maximum pleasure is max((3-2),(4-2))=2;

In the second example,he can ignore book 5 and spilt the first 4 books into 4 parts,give them to his classmates.

思路
二分答案,问题就转化为求一个下降子序列的问题;
构造一个前缀和数组,求以第一个结点开头且后一个结点值减前一个结点小于等于二分的结果,这个序列长度大于k则二分结果成立;
用树状数组来维护降序的以每个点结尾的序列长度;
更新时需要将当前点的值减m,然后在降序的排列里找到位置,再利用前缀数组获取最值更新。

参考代码

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const ll NINF=-(1ll<<61);
const int MAX_N=2e5+5;

struct node{
    ll s;
    int id;
};

int n,k;
ll a[MAX_N+2];
node data[MAX_N+2];
int ii[MAX_N+2];
ll b[MAX_N+2];
int bit[MAX_N+2];

bool cmp(node A,node B){
    return A.s>B.s;
}
bool cmp2(node A,node B){
    return A.id<B.id;
}

void add(int i,int x){
    while(i<=n){
        bit[i]=max(bit[i],x);
        i+=i&-i;
    }
}
ll sum(int i){
    int s=-1;
    while(i>0){
        s=max(s,bit[i]);
        i-=i&-i;
    }
    return s;
}

int find(ll x){
    int lb=0,ub=n+1;
    while(ub-lb>1){
        int mid=(lb+ub)/2;
        if(b[mid]>=x)lb=mid;
        else ub=mid;
    }
    return lb;
}

bool can(ll m){
    fill(bit,bit+n+1,-1);
    add(ii[1],0);
    for(int i=2;i<=n;i++){
        int j=find(data[i].s-m);
        int ans=sum(j);
        if(ans!=-1){
            if(ans>=k-1)return true;
            add(ii[i],ans+1);
        }
    }
    return false;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&k);
        data[1].s=0,data[1].id=1;
        for(int i=2;i<=n+1;i++){
            scanf("%lld",a+i);
            data[i].s=data[i-1].s+a[i];
            data[i].id=i;
        }
        n++;
        sort(data+1,data+n+1,cmp);
        for(int i=1;i<=n;i++){
            ii[data[i].id]=i;
            b[i]=data[i].s;
        }
        sort(data+1,data+n+1,cmp2);
        ll lb=-2e14-1,ub=1e9+1;
        while(ub-lb>1){
            ll mid=(lb+ub)/2;
            if(can(mid))ub=mid;
            else lb=mid;
        }
        printf("%lld\n",ub);
    }
	return 0;
}
### 关于Out-of-Distribution (OOD) 检测 #### OOD概念定义 在机器学习领域,尤其是深度学习中,模型通常被训练用于识别来自特定数据分布的样本。然而,在实际应用场景下,输入的数据可能并不遵循训练集中的分布模式。这些不遵循预期分布规律的新颖或者异常样例被称为Out-of-Distribution(OOD)[^1]。 #### 处理方法概述 为了有效应对OOD问题,研究人员提出了种策略和技术来增强模型对于未知类别或异常情况下的鲁棒性和泛化能力: - **基于置信度的方法**:通过评估模型给出的概率分布特性(如熵),可以判断测试实例是否属于已知分类之外。当预测结果显示出较高的不确定性时,则认为该样本可能是OOD [^3]。 - **证据理论驱动的学习框架**:引入狄利克雷先验作为不确定性的表示形式,并调整网络结构使其能够显式地估计这种不确定性水平。这种方法允许区分高可信度的正常类成员与其他潜在的异常点 。 - **对比学习与自监督机制**:利用未标记的大规模数据集构建辅助任务,从而让特征提取器学会捕捉更广泛而稳定的语义信息,有助于提高对不同域间变化的适应力 [^2]。 #### PyTorch实现案例 针对上述提到的技术路线之一——基于置信度的OOD检测方案,下面提供了一个简单的Python代码片段展示如何计算并筛选出疑似OOD样本的过程: ```python import torch.nn.functional as F def detect_ood(logits, threshold=0.9): probs = F.softmax(logits, dim=-1) max_probs, _ = torch.max(probs, dim=-1) ood_mask = max_probs < threshold return ood_mask.cpu().numpy() ``` 此函数接收神经网络最后一层输出logits以及设定好的阈值参数threshold,默认情况下取值为0.9;返回布尔数组指示哪些位置对应着可能存在的OOD项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值