[loj3523]分糖果
做法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]分糖果的更多相关文章
- CSDN 分糖果算法的思路和求助
昨天晚上 在csdn上做了一道分糖果的题目,我自个测的是没有问题,但是提交答案后,老失败,提示 你的程序正常运行并输出了结果,但是答案错误你的程序输出结果与测试数据中的输出结果不符 我先把自个思路说一 ...
- hunnu11543:小明的烦恼——分糖果
Problem description 小明在班里一直是个非常公正的孩子.这点同学和老师都非常清楚,这不,老师每周都会从家里带来一些糖果.然后叫小明把糖果分给其它小朋友,但这个班里的同学都有一个非 ...
- [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现
[LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...
- C语言 · 分糖果
历届试题 分糖果 时间限制:1.0s 内存限制:256.0MB 问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一 ...
- 蓝桥杯 历届试题 PREV-32 分糖果
历届试题 分糖果 时间限制:1.0s 内存限制:256.0MB 问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半给左手边 ...
- 牛客 2018NOIP 模你赛2 T2 分糖果 解题报告
分糖果 链接:https://www.nowcoder.com/acm/contest/173/B 来源:牛客网 题目描述 \(N\) 个小朋友围成一圈,你有无穷个糖果,想把其中一些分给他们. 从某个 ...
- 51nod——1402最大值、2479小b分糖果 (套路)
1402最大值:正向从1到n,如果没有限制,就依次递增1,如果有限制,就取那个限制和递增到这的最小值.这样保证1和每个限制点后面都是符合题意的递增,但是限制点前面这个位置可能会有落差(之前递增多了). ...
- 58同城笔试题:数组去重;分饼干(分糖果);最小路径和(leetcode64)
1. 数组去重 题目描述 /** * 有序数组去重 * 输出最终的数字个数 * 输入:1,2,2 * 输出:2 * @author Turing * */ 代码 import java.util.*; ...
- HNUSTOJ-1639 分糖果(几何)
1639: 分糖果 时间限制: 1 Sec 内存限制: 128 MB提交: 261 解决: 118[提交][状态][讨论版] 题目描述 为了实验室的发展,吴大大采购了一箱零食O(∩_∩)O~~ 在 ...
随机推荐
- Windows用cmd编译运行C程序
在Windows环境下用命令行编译运行程序 浙江大学-C语言程序设计进阶 配置gcc 准备一个Dev-cpp 找到gcc.exe所在目录 Dev-Cpp\MinGW64\bin 地址栏右键将地址复制为 ...
- 以太坊web3开发初步学习
以太坊web3开发初步学习 此文是对https://learnblockchain.cn/2018/04/15/web3-html/的学习再理解. 以太坊智能合约通过使用web3.js前端和智能合约交 ...
- python爬虫时,解决编码方式问题的万能钥匙(uicode,utf8,gbk......)
转载 原文:https://blog.csdn.net/xiongzaiabc/article/details/81008330 无论遇到的网页代码是何种编码方式,都可以用以下方法统一解决 imp ...
- MarkDown之Typora使用
Typora:所见即所得 常用快捷键 加粗:ctrl + B 标题:ctrl + 16,对于与16级标题 插入公式:ctrl + Shift + m 插入代码:ctrl + Shift + K 插入图 ...
- maven编码 gbk 的不可映射字符
解决这个问题的思路: 在maven的编译插件中声明正确的字符集编码编码--编译使用的字符集编码与代码文件使用的字符集编码一致!! 安装系统之后,一般中文系统默认字符集是GBK.我们安装的软件一般都继承 ...
- SpringCloud 2020.0.4 系列之服务降级
1. 概述 老话说的好:做人要正直,做事要正派,胸怀坦荡.光明磊落,才会赢得他人的信赖与尊敬. 言归正传,之前聊了服务间通信的组件 Feign,今天我们来聊聊服务降级. 服务降级简单的理解就是给一个备 ...
- 使用registry搭建docker私服仓库
使用registry搭建docker私服仓库 一.拉取 registry镜像 二.根据镜像启动一个容器 1.创建一个数据卷 2.启动容器 三.随机访问一个私服的接口,看是否可以返回数据 四.推送一个镜 ...
- $dy$讲课总结
字符串: 1.广义后缀自动机(大小为\(m\))上跑一个长度为\(n\)的串,所有匹配位置及在\(parent\)树上其祖先的数量的和为\(min(n^2,m)\),单次最劣是\(O(m)\). 但是 ...
- CSP2021 翻车记
DAY - INF 日常模拟赛被吊打,不知道为啥总是出一些小问题导致正解gg,成绩的话也就是中游吧,不过方差不小 DAY - 2 感冒了,头疼得很,签到题甚至也签到失败了,烦得很 DAY -1 全真体 ...
- zabbix 监控redis 挂掉自动重启 并发送企业微信
1.创建redis监控项[配置]-[主机]-[监控项]-创建监控项,监控6379端口(注意关闭防火墙或者开启防火墙端口6379) redis配置文件设置允许任何地址监听: 添加监控项 2.创建redi ...