热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

2019MultiUniversityTrainingContest31007Findtheanswer——线段树

Thisway题意:给你n个数,让你从1到n输出一个数,这个数是说让你从1到i-1中最少去掉几个数使得1-i的sum

This way

题意:

给你n个数&#xff0c;让你从1到n输出一个数&#xff0c;这个数是说让你从1到i-1中最少去掉几个数使得1-i的sum<&#61;m。

题解&#xff1a;

我们去肯定是去掉最大的那几个&#xff0c;保留小的。那么我们就可以先离散化求出每个值是在原数组中的第几小。建树按照这个建。维护的值是前缀和&#xff0c;也就是说新加入一个数&#xff0c;将i-n的所有位置上都加上a[i]&#xff0c;这样我们之后直接找<&#61;m-a[i]的最大位置即可。query返回这个区间有多少个值。
最狗的一点是&#xff0c;需要在每次输出最后加上空格&#xff1f;&#xff1f;这是出题人的问题吧。

#include
using namespace std;
#define ll long long
const int N&#61;2e5&#43;5;
ll a[N],b[N],num[N*4],mi[N*4],mx[N*4],flag[N*4];
int fa[N];
int finds(int x)
{return x&#61;&#61;fa[x]?x:fa[x]&#61;finds(fa[x]);
}
void push_down(int root)
{if(!flag)return ;flag[root<<1]&#43;&#61;flag[root];flag[root<<1|1]&#43;&#61;flag[root];mi[root<<1]&#43;&#61;flag[root];mi[root<<1|1]&#43;&#61;flag[root];mx[root<<1]&#43;&#61;flag[root];mx[root<<1|1]&#43;&#61;flag[root];flag[root]&#61;0;
}
void update(int l,int r,int root,int ql,int qr,int val,int f)
{if(l>&#61;ql&&r<&#61;qr){if(!f)num[root]&#43;&#43;;elsemi[root]&#43;&#61;val,mx[root]&#43;&#61;val,flag[root]&#43;&#61;val;return ;}push_down(root);int mid&#61;l&#43;r>>1;if(mid>&#61;ql)update(l,mid,root<<1,ql,qr,val,f);if(mid}
int query(int l,int r,int root,int val)
{if(l&#61;&#61;r)return mi[root]<&#61;val?num[root]:0;push_down(root);int mid&#61;l&#43;r>>1;if(mx[root]<&#61;val)return num[root];if(mx[root<<1]<&#61;val){int ans&#61;num[root<<1];if(mi[root<<1|1]<&#61;val)ans&#43;&#61;query(mid&#43;1,r,root<<1|1,val);return ans;}if(mi[root<<1]<&#61;val)return query(l,mid,root<<1,val);return 0;
}
int main()
{int q;scanf("%d",&q);while(q--){ll n,m;scanf("%lld%lld",&n,&m);for(int i&#61;0;i<&#61;n*4;i&#43;&#43;)mi[i]&#61;mx[i]&#61;num[i]&#61;flag[i]&#61;0;for(int i&#61;1;i<&#61;n;i&#43;&#43;)scanf("%lld",&a[i]),b[i]&#61;a[i],fa[i]&#61;i;sort(b&#43;1,b&#43;1&#43;n);for(int i&#61;1;i<&#61;n;i&#43;&#43;){int x&#61;lower_bound(b&#43;1,b&#43;1&#43;n,a[i])-b;a[i]&#61;finds(x);fa[a[i]]&#61;a[i]&#43;1;finds(x);}printf("0 ");for(int i&#61;2;i<&#61;n;i&#43;&#43;){update(1,n,1,a[i-1],a[i-1],1,0);update(1,n,1,a[i-1],n,b[a[i-1]],1);int nn&#61;query(1,n,1,m-b[a[i]]);printf("%d ",i-1-nn);}printf("\n");}return 0;
}


推荐阅读
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 由二叉树到贪心算法
    二叉树很重要树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。单就面试而言,在 ... [详细]
  • JavaScript中的数组是数据集合的核心结构之一,内置了多种实用的方法。掌握这些方法不仅能提高开发效率,还能显著提升代码的质量和可读性。本文将详细介绍数组的创建方式及常见操作方法。 ... [详细]
  • 本文探讨了符号三角形问题,该问题涉及由相同数量的“+”和“-”符号组成的三角形。通过递归回溯法,可以有效地搜索并计算符合条件的符号三角形的数量。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • HDU 2871 内存管理问题(线段树优化)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871。本题涉及内存管理操作,包括重置、申请、释放和查询内存块。通过使用线段树进行高效管理和维护。 ... [详细]
  • 本题探讨如何在两个长度为 n 的整数序列中,找到它们的最长公共子序列(LCS)。题目保证第一个序列中的元素各不相同。我们将深入分析并提供一种高效的求解方法。 ... [详细]
  • 本文介绍了一个经典的算法问题——活动选择问题,来源于牛客网的比赛题目。该问题要求从一系列活动集合中选出最多数量的相容活动,确保这些活动的时间段不重叠。 ... [详细]
  • KMP算法是一种高效的字符串模式匹配算法,能够在不进行回溯的情况下完成匹配,其时间复杂度为O(m+n),其中m和n分别为文本串和模式串的长度。本文将详细介绍KMP算法的工作原理,并提供C语言实现。 ... [详细]
  • 本文详细解析了2019年西安邀请赛中的一道树形动态规划题目——J题《And And And》。题目要求计算树中所有子路径异或值为0的集合数量,通过深入分析和算法优化,提供了高效的解决方案。 ... [详细]
  • 本文探讨了如何使用pg-promise库在PostgreSQL中高效地批量插入多条记录,包括通过事务和单一查询两种方法。 ... [详细]
  • 本文介绍了一种基于选择排序思想的高效排序方法——堆排序。通过使用堆数据结构,堆排序能够在每次查找最大元素时显著提高效率。文章详细描述了堆排序的工作原理,并提供了完整的C语言代码实现。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • 本文详细介绍了Java中的注解功能,包括如何定义注解类型、设置注解的应用范围及生命周期,并通过具体示例展示了如何利用反射机制访问注解信息。 ... [详细]
  • 掌握Mosek矩阵运算,轻松应对优化挑战
    本篇文章继续深入探讨Mosek学习笔记系列,特别是矩阵运算部分,这对于优化问题的解决至关重要。通过本文,您将了解到如何高效地使用Mosek进行矩阵初始化、线性代数运算及约束域的设定。 ... [详细]
author-avatar
张丽君2502934023
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有