做法1

将问题离线,并在左端点和右端点打上差分,之后即可以看作求$f(C,[a_{1},a_{2},...,a_{n}])$,其表示以$C$为上限(0为下限),从0开始不断加上$a_{i}$(可以为负)的答案

再定义$g(C,a_{i})$,其与$f(C,a_{i})$的定义类似,但没有下限为0的限制

考虑两者的关系,显然$\forall 0\le j\le n$有
$$
f(C,[a_{1},a_{2},...,a_{n}])\ge f(C,[a_{j+1},a_{j+2},...,a_{n}])\ge g(C,[a_{j+1},a_{j+2},...,a_{n}])
$$
前者是因为在操作$a_{j-1}$后值非负,后者因为其没有下限显然值不增

另一方面,考虑最大的$j$,使得在$f(C,a_{i})$中操作$a_{j}$后值为0,即之后不会再变为0,那么也可以看作没有下限为0的限制,即有
$$
f(C,[a_{1},a_{2},...,a_{n}])=f(C,[a_{j+1},a_{j+2},...,a_{n}])=g(C,[a_{j+1},a_{j+2},...,a_{n}])
$$
(若不存在则令$j=0$,相等的原因类似,这里就省略了)

由此,我们得到了$f(C,[a_{1},a_{2},...,a_{n}])=\max_{0\le j\le n}g(C,[a_{j+1},a_{j+2},...,a_{n}])$

考虑$g(C,[a_{1},a_{2},...,a_{n}])$,令$S_{i}=\sum_{j=1}^{i}a_{j}$,若不存在$S_{i}>C$即为$S_{n}$,否则即$S_{n}-\max_{1\le i\le n}S_{i}+C$

将之代入前式并化简,也即
$$
f(C,[a_{1},a_{2},...,a_{n}])=S_{n}-\min_{0\le i\le n}\max(S_{i},\max_{i\le j\le n}S_{j}-C)
$$
考虑如何维护,二分枚举答案$T$,那么$f(C,a_{i})>T$当且仅当
$$
\exists 0\le i\le n,\max(S_{i},\max_{i\le j\le n}S_{j}-C)<S_{n}-T
$$
换言之,我们即要检验是否存在$S_{i}<S_{n}-T$且$\forall i\le j\le n,S_{j}<S_{n}-T+C$,显然后者具有单调性,通过线段树可以确定$i$的下限,然后求区间最小值即可

时间复杂度为$o(n\log^{2}n)$,可以通过

 1 #include<bits/stdc++.h>
2 #include"candies.h"
3 using namespace std;
4 #define N 200005
5 #define ll long long
6 #define L (k<<1)
7 #define R (L+1)
8 #define mid (l+r>>1)
9 vector<int>ans,Add[N],Dec[N];
10 int n,m;
11 ll tag[N<<2],mx[N<<2],mn[N<<2];
12 void upd(int k,ll x){
13 tag[k]+=x;
14 mx[k]+=x;
15 mn[k]+=x;
16 }
17 void up(int k){
18 mx[k]=max(mx[L],mx[R]);
19 mn[k]=min(mn[L],mn[R]);
20 }
21 void down(int k){
22 upd(L,tag[k]);
23 upd(R,tag[k]);
24 tag[k]=0;
25 }
26 void update(int k,int l,int r,int x,int y,int z){
27 if ((l>y)||(x>r))return;
28 if ((x<=l)&&(r<=y)){
29 upd(k,z);
30 return;
31 }
32 down(k);
33 update(L,l,mid,x,y,z);
34 update(R,mid+1,r,x,y,z);
35 up(k);
36 }
37 ll query(int k,int l,int r,int x,int y){
38 if ((l>y)||(x>r))return 2e15;
39 if ((x<=l)&&(r<=y))return mn[k];
40 down(k);
41 return min(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
42 }
43 int find(int k,int l,int r,ll x){
44 if (mx[k]<x)return -1;
45 if (l==r)return l;
46 down(k);
47 int ans=find(R,mid+1,r,x);
48 if (ans>=0)return ans;
49 return find(L,l,mid,x);
50 }
51 int query(int k){
52 int l=0,r=k;
53 ll S=query(1,0,m,m,m);
54 while (l<r){
55 int x=find(1,0,m,S-mid+k);
56 if (query(1,0,m,x+1,m)>=S-mid)r=mid;
57 else l=mid+1;
58 }
59 return l;
60 }
61 vector<int> distribute_candies(vector<int>c,vector<int>l,vector<int>r,vector<int>v){
62 n=c.size(),m=l.size();
63 for(int i=0;i<m;i++){
64 Add[l[i]].push_back(i);
65 Dec[r[i]].push_back(i);
66 }
67 for(int i=0;i<n;i++){
68 for(int j=0;j<Add[i].size();j++)update(1,0,m,Add[i][j]+1,m,v[Add[i][j]]);
69 ans.push_back(query(c[i]));
70 for(int j=0;j<Dec[i].size();j++)update(1,0,m,Dec[i][j]+1,m,-v[Dec[i][j]]);
71 }
72 return ans;
73 }

做法2

仍然离线+差分,考虑递归处理$f(C,[a_{1},a_{2},...,a_{n}],x)$的值($x$指操作前的值,初始为0)

令$sum_{i}=\sum_{j=1}^{i}a_{j}$,$mx$为$sum_{i}$的最大值(包括$sum_{0}$),$mn$为最小值,对其分类讨论:

1.若$x+mx\le C$或$x+mn\ge 0$,即没有上限或下限,与之前的$g$类似

2.注意到$C-mx<x<-mn$,也即$mx-mn>C$,则$f(C,a_{i},0)=f(C,a_{i},1)=...=f(C,a_{i},C)$

由此,可以递归处理,当右子树$mx-mn>C$显然就不用递归左子树了,否则递归左子树后右子树的结果可以直接$o(1)$求出

时间复杂度为$o(n\log n)$,可以通过

[loj3523]分糖果的更多相关文章

  1. CSDN 分糖果算法的思路和求助

    昨天晚上 在csdn上做了一道分糖果的题目,我自个测的是没有问题,但是提交答案后,老失败,提示 你的程序正常运行并输出了结果,但是答案错误你的程序输出结果与测试数据中的输出结果不符 我先把自个思路说一 ...

  2. hunnu11543:小明的烦恼——分糖果

    Problem description   小明在班里一直是个非常公正的孩子.这点同学和老师都非常清楚,这不,老师每周都会从家里带来一些糖果.然后叫小明把糖果分给其它小朋友,但这个班里的同学都有一个非 ...

  3. [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现

    [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...

  4. C语言 · 分糖果

    历届试题 分糖果   时间限制:1.0s   内存限制:256.0MB      问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一 ...

  5. 蓝桥杯 历届试题 PREV-32 分糖果

    历届试题 分糖果   时间限制:1.0s   内存限制:256.0MB 问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半给左手边 ...

  6. 牛客 2018NOIP 模你赛2 T2 分糖果 解题报告

    分糖果 链接:https://www.nowcoder.com/acm/contest/173/B 来源:牛客网 题目描述 \(N\) 个小朋友围成一圈,你有无穷个糖果,想把其中一些分给他们. 从某个 ...

  7. 51nod——1402最大值、2479小b分糖果 (套路)

    1402最大值:正向从1到n,如果没有限制,就依次递增1,如果有限制,就取那个限制和递增到这的最小值.这样保证1和每个限制点后面都是符合题意的递增,但是限制点前面这个位置可能会有落差(之前递增多了). ...

  8. 58同城笔试题:数组去重;分饼干(分糖果);最小路径和(leetcode64)

    1. 数组去重 题目描述 /** * 有序数组去重 * 输出最终的数字个数 * 输入:1,2,2 * 输出:2 * @author Turing * */ 代码 import java.util.*; ...

  9. HNUSTOJ-1639 分糖果(几何)

    1639: 分糖果 时间限制: 1 Sec  内存限制: 128 MB提交: 261  解决: 118[提交][状态][讨论版] 题目描述 为了实验室的发展,吴大大采购了一箱零食O(∩_∩)O~~ 在 ...

随机推荐

  1. 迁移appseting.json创建自定义配置中心

    创建一个自定义的配置中心,将框架中各类配置,迁移至数据库,支持切换数据库,热重载. 说在前面的话 自使用.net Core框架以来,配置大多存在json文件中: [框架默认加载配置]文件为appset ...

  2. noip2017D1T3逛公园(拓扑图上dp,记忆化搜索)

    QWQ前几天才刚刚把这个D1T3写完 看着题解理解了很久,果然我还是太菜了QAQ 题目大意就是 给你一个n个点,m条边的图,保证1能到达n,求从1到n的 (设1到n的最短路长度是d)路径长度在[d,d ...

  3. 论文解读(MPNN)Neural Message Passing for Quantum Chemistry

    论文标题:DEEP GRAPH INFOMAX 论文方向:  论文来源:ICML 2017 论文链接:https://arxiv.org/abs/1704.01212 论文代码: 1 介绍 本文的目标 ...

  4. 2021.1.28--vj补题

    B - B CodeForces - 994B 题内容: Unlike Knights of a Round Table, Knights of a Polygonal Table deprived ...

  5. 【UE4 C++】简单获取名称、状态、时间、帧数、路径与FPaths

    基于UKismetSystemLibrary 获取各类名称 // Returns the actual object name. UFUNCTION(BlueprintPure, Category = ...

  6. Flink sql 之 join 与 StreamPhysicalJoinRule (源码解析)

    源码分析基于flink1.14 Join是flink中最常用的操作之一,但是如果滥用的话会有很多的性能问题,了解一下Flink源码的实现原理是非常有必要的 本文的join主要是指flink sql的R ...

  7. Java:容器类线程不安全

    Java:容器类线程不安全 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. Collection 线程不安全的举例 前言 1.当我们执行下面语句的时候,底层 ...

  8. 【二食堂】Alpha - Scrum Meeting 10

    Scrum Meeting 10 例会时间:4.20 18:00~18:20 进度情况 组员 昨日进度 今日任务 李健 1. 与柴博合作完成登录注册页面issue 继续完成登录注册页面issue 柴博 ...

  9. alertmanager的使用

    alertmanager的使用 一.Alertanager的安装 1.下载 2.安装 3.启动 4.alertmanager和prometheus的整合 二.告警分组 1.告警规则 2.alertma ...

  10. Ajax配合后端实现Excel的导出

    一.需求 在我们的日常开发中,可能经常需要遇到excel的导出,以往excel的导出服务器端都是使用的 GET 方法,但是某些情况下,服务器端只能使用 POST 方法,那么我们有没有好的方法实现exc ...