首页 > 其他分享 >洛谷P6169 [IOI2016] Molecules

洛谷P6169 [IOI2016] Molecules

时间:2024-02-16 21:33:39浏览次数:28  
标签:P6169 可行 洛谷 最大数 int IOI2016 long mid ans

洛谷传送门

分析

结论:如果存在解,则一定有一个解使得选的数是排序后的一段前缀并上一段后缀。

下文所说序列均已排序。

引理:对于一个可行解选的某个数,一定可以将其换成序列中的最小数或最大数而使得换完之后还是一个可行解。

证明:反证法。假设都不可换。

设当前选的所有数的和为 \(s\),限制为 \(\ge L\) 且 \(\le R\),所给的所有重量最大值为 \(r\),最小值为 \(l\)。要换掉的数为 \(x\)。

先考虑换成最大数,则不可换等价于 \(r - x > R - s\)。

同理不可换为最小数等价于 \(x - l > s - L\)。

由于都不可换,所以两式同时成立。于是两式相加,得 \(r - l > R - L\),与题目所给限制条件矛盾。所以必有至少一个方向可换。

证毕。

根据引理弱化可得,必然可以将可行解中的某个数变大或变小(换之后要保证在给定数中),而保证换之后仍为可行解。

那么我们随便考虑一个可行解,从左往右看选的每个数。我们肯定可以把这个数换成还未选的最大数或最小数,而且换完之后还是可行解。

于是必然可以把这个可行解中所有选的数都堆到前缀或后缀上。从而必存在一个可行解是一段前缀并上一段后缀。

于是枚举右端点,符合条件的左端点必为一段区间。搞出这个区间的左右端点,即可判断是否可行。注意不要选到重复数。记得判无解。

代码

#include <bits/stdc++.h>
using namespace std;
pair<long long, int> a[2000005];
long long pre[200005];
// first >=
int n, l, r;
vector<int> ans;
int bck[200005];
int Search1(long long x) {
    int l = 1, r = n, mid, ans = n + 1;
    while (l <= r) {
        mid = (l + r) >> 1;
        if (pre[mid] >= x)
            ans = mid, r = mid - 1;
        else
            l = mid + 1;
    }
    return ans;
}
// last <=
int Search2(long long x) {
    int l = 1, r = n, mid, ans = -1;
    while (l <= r) {
        mid = (l + r) >> 1;
        if (pre[mid] <= x)
            ans = mid, l = mid + 1;
        else
            r = mid - 1;
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> l >> r;
    for (int i = 1; i <= n; i++) cin >> a[i].first;
    for (int i = 1; i <= n; i++) a[i].second = i;
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) pre[i] = pre[i - 1] + a[i].first;
    long long suf = 0;
    for (int i = n + 1; i; --i) {
        suf += a[i].first;
        if (suf >= l && suf <= r) {
            cout << n - i + 1 << "\n";
            while (i <= n) cout << (a[i++].second) - 1 << " ";
            return 0;
        }
        int x = Search1(l - suf);
        int y = min(i - 1, Search2(r - suf));
        if (x <= y) {
            cout << n - i + 1 + x << "\n";
            while (x) cout << (a[x--].second) - 1 << " ";
            while (i <= n) cout << (a[i++].second) - 1 << " ";
            return 0;
        }
    }
    cout << 0 << "\n";
    return 0;
}

标签:P6169,可行,洛谷,最大数,int,IOI2016,long,mid,ans
From: https://www.cnblogs.com/forgotmyhandle/p/18017504

相关文章

  • 洛谷 P4065 题解
    模拟赛T1,纪念一下第一次场切紫。(话说场上这么多人切是不是都找到原了,就我这么傻想了半天)正难则反,很容易的将题目转化为选择若干种颜色,使这些颜色在原数组中的位置连续。设$pre_i$为颜色$i$最早出现的位置,$suf_i$为颜色$i$最晚出现的位置。假设通过选择若干颜色得到的位......
  • 洛谷 P9912 [COCI 2023/2024 #2] Zatopljenje 题解
    首先发现区间中的个数等于\(\texttt{高度大于x的位置的个数}-\texttt{连续两个位置都是大于x的位置的个数}\)。具体令\(H_i=\min(h_i,h_{i+1})(i\in[1,n-1])\),那么对于一次询问答案\(ans=\sum\limits_{i=l}^{r}[h_i>x]-\sum\limits_{i=l}^{r-1}[H_i>x]\),其......
  • 洛谷【算法1-5】 贪心
    P2240【深基12.例1】部分背包问题-洛谷|计算机科学教育新生态(luogu.com.cn)#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=110;intn,t;structnode{intm,v;};boolcmp(nodeaa,nodebb){returnaa.v*bb.m>bb.v*aa.m......
  • 「杂题乱刷」洛谷 P1831
    题目链接一道简单数位dp题。多设一个支点和力矩和然后套板子就做完了。参考代码:点击查看代码/*Tips:你数组开小了吗?你MLE了吗?你觉得是贪心,是不是该想想dp?一个小时没调出来,是不是该考虑换题?*/#include<bits/stdc++.h>usingnamespacestd;#definemapunordered_m......
  • 【题单】一个动态更新的洛谷综合题单
    洛谷试炼场的题目确实很具有代表性,但是近几年以来,又有许多经典题目出现在OI界中,这个大题单就是作为洛谷试炼场的扩展和补充。目录新版本食用指南更新日志题单Part0试机题Part1入门阶段Part2基础算法Part3搜索Part4动态规划Part4.1-4.4动态规划Part4.5-4.12动态规......
  • 「杂题乱刷」洛谷 P10155
    题目链接P10155[LSOT-2]基于二分查找与插入的快速排序解题思路算法一:容易发现,当\(a_n\)不为\(n\)时,我们无论如何都无法将\(n\)这个值插入到最后一位,否则我们可以依次将所有数字从大到小插入,这样也可以保证失去最少的贡献。视写法获得\(40\)分或\(60\)分。算法二......
  • 洛谷P5725 【深基4.习8】求三角形
    洛谷P5725【深基4.习8】求三角形【深基4.习8】求三角形题目描述模仿例题,打印出不同方向的正方形,然后打印三角形矩阵。中间有个空行。输入格式输入矩阵的规模,不超过9。输出格式输出矩形和正方形样例#1样例输入#14样例输出#101020304050607080910111213141516......
  • 洛谷 P1795 无穷的序列 题解
    题目传送门题目大意:给定整数\(a\),判断\(a\)是否属于数列\(1,2,4,7,11\cdots\)。多测。1.暴力枚举(90pts)不难发现,该数列除第一项外第\(n\)项比第\(n-1\)项多\(n-1\)。故暴力枚举\(n\),计算数列的每一项,判断是否与\(a\)相等,大于\(a\)就break。多测加记忆化,用mx......
  • 洛谷P3455 笔记
    传送门又是一道看了tj的题。题意\(t\)次询问,每次询问给定\(n\),\(m\),\(k\),求\(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=k]\)。\(1\let\le5\times10^4\),\(1\lek\len\),\(m\le5\times10^4\)正文把\(k\)扔到上界去,记原式变为\(\sum_{i=1}^{\lfloor\frac{n}{k}......
  • 【洛谷 P2670】[NOIP2015 普及组] 扫雷游戏 题解(模拟)
    [NOIP2015普及组]扫雷游戏题目背景NOIP2015普及组T2题目描述扫雷游戏是一款十分经典的单机小游戏。在行列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的......