可持久化线段树15(思维+乱搞)

这篇具有很好参考价值的文章主要介绍了可持久化线段树15(思维+乱搞)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

P4559 [JSOI2018]列队

首先思考:

对于 [ l , r ] [l,r] [l,r]区间内的同学,他们集合之后与集合之前的相对大小是不会改变的,所有无论是否集合他们的相对的顺序是不变的,那么集合到 [ k , k + r − l ] [k,k+r-l] [k,k+rl]的时候,他们的位置一定是固定的,我们可以将其称之为最终位,我们将他们的相对大小记为 r a n k i rank_i ranki

那么这么思考,有一部分一定往右跑,有一部分一定往左跑。

如果一个同学向右跑,他的起始位置都知道,那么他跑的距离就是 k + r a n k i − 1 − a i k+rank_i-1-a_i k+ranki1ai

如果想做跑,那么他跑的距离就是 − ( k + r a n k i − 1 − a i ) -(k+rank_i-1-a_i) (k+ranki1ai)

我们可以采取主席树来存他们的位置,那么就相当于一个区间前缀的问题,如果在一个子区间内所有同学都像同一个方向跑,那么就可以直接得出答案。

首先对于这个区间,我们可以确定在这个区间内的同学的 r a n k i rank_i ranki一定是连续的,以往右跑的同学为例他们跑的距离的总和就是 ( k − 1 + r k l − a l ) + . . . . + ( k − 1 + r k r − a r ) = − ∑ a i + ∑ ( k − 1 + r k i ) (k-1+rk_l-a_l)+....+(k-1+rk_r-a_r)=-{\sum{a_i}}+{\sum{(k-1+rk_i)}} (k1+rklal)+....+(k1+rkrar)=ai+(k1+rki),其中 r k i rk_i rki是差为 1 1 1,且长度为 r − l + 1 r-l+1 rl+1的等差数列,可以利用等差数列求和的方式求得。另外注意,等差数列的项数应当是这个区间的人数,而不是 r − l + 1 r-l+1 rl+1。根据上述的推理我们很容易发现想做跑的同学距离和为 ∑ a i − ∑ ( k − 1 + r k i ) {\sum{a_i}}-{\sum{(k-1+rk_i)}} ai(k1+rki)

那么我们如何判断一个区间可以用于求解呢?

首先我们判断这个区间的人是往左跑还是往右跑,如果一个区间的人往左跑,那么很容易发现其判定条件是 p o s > = k + ∑ s i z e l s pos>=k+{\sum{size_{ls}}} pos>=k+sizels s i z e l s size_{ls} sizels代表这个区间左边的人的个数,往右跑的稍微难想一点,答案是 p o s < = k + ∑ s i z e l s + ∑ s i z e l e n − 1 pos<=k+{\sum{size_{ls}}}+{\sum{size_{len}}}-1 pos<=k+sizels+sizelen1,其中 ∑ s i z e l e n {\sum{size_{len}}} sizelen代表在 [ l , r ] [l,r] [l,r]中的人数。

对于人数的求取我们可以采取权值线段树存数的个数,对于 ∑ a i {\sum{a_i}} ai我们可以用主席树维护其前缀和,做法和今年ICPC昆明的M题有异曲同工之妙。文章来源地址https://www.toymoban.com/news/detail-485603.html


#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
//#define int long long
//#define double long double
#define re register int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=998244353;
const int M=1e8+5;
const int N=1e6+5;//?????????? 4e8
int rt[N];
int tot,n,m;
struct node
{
	int l,r;
	ll sum,val;
}e[N*80];
void insert(int &p,int pre,int l,int r,int pos)
{
	e[++tot]=e[pre];
	p=tot;
	e[tot].sum+=pos,e[tot].val++;
	if(l==r)  return;
	int mid=(l+r)>>1;
	if(pos<=mid)  insert(e[p].l,e[pre].l,l,mid,pos);
	else  insert(e[p].r,e[pre].r,mid+1,r,pos);
}
ll ask(int L,int R,int l,int r,int k,int f)
{
	ll sum=e[R].sum-e[L].sum;
	ll val=e[R].val-e[L].val;
	if(val==0)  return 0;
	if(l>=f+k)  return sum-(2*k+2*f+val-1)*val/2;
	if(r<=k+f+val-1)  return -sum+(2*k+2*f+val-1)*val/2;
	int mid=(l+r)>>1;
	return ask(e[L].l,e[R].l,l,mid,k,f)+ask(e[L].r,e[R].r,mid+1,r,k,f+e[e[R].l].val-e[e[L].l].val);
}
void solve()
{
	cin>>n>>m;
	for(re i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		insert(rt[i],rt[i-1],1,N-5,x);
	}
	while(m--)
	{
		int l,r,k;
		scanf("%d%d%d",&l,&r,&k);
		printf("%lld\n",ask(rt[l-1],rt[r],1,N-5,k,0));
	}
}
signed main()
{
    int T=1;
//    cin>>T;
    for(int index=1;index<=T;index++)
    {
//        printf("Case %d:\n",index);
        solve();
//        puts("");
    }
    return 0;
}
/*


1
6 5
0 0 0 122 499 8888




*/

到了这里,关于可持久化线段树15(思维+乱搞)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • redis持久化【RDB+AOF】持久化双雄

    这是redis系列文章之《redis持久化【RDB+AOF】持久化双雄》,上一篇文章【redis基础】redis的十大数据类型_努力努力再努力mlx的博客-CSDN博客 感谢大家的支持~ 目录 RDB 什么是RDB RDB的作用 配置文件关于RDB部分  6vs7 操作步骤 修改配置文件(本案例设置5s修改2次) 修改dump文件的保

    2024年02月08日
    浏览(74)
  • RabbitMQ系列(8)--实现RabbitMQ队列持久化及消息持久化

    概念:在上一章文章中我们演示了消费者宕机的情况下消息没有被消费成功后会重新入队,然后再被消费,但如何保障RabbitMQ服务停掉的情况下,生产者发过来的消息不会丢失,这时候我们为了消息不会丢失就需要将队列和消息都标记为持久化。 1、实现RabbitMQ队列持久化 只需

    2024年02月09日
    浏览(38)
  • 全面解析 Redis 持久化:RDB、AOF与混合持久化

    前言: 每次你在游戏中看到玩家排行榜,或者在音乐应用中浏览热门歌单,有没有想过这个排行榜是如何做到实时更新的?当然,依靠 Redis 即可做到。 在技术领域,我们经常听到 「键值存储」 这个词。但在 Redis 的世界里,这只是冰山一角。Redis 的对象,不仅仅是简单的数据

    2024年03月10日
    浏览(63)
  • Redis 持久化-RDB和 持久化-AOF 的详细介绍以及区别

    在线文档: https://redis.io/topics/persistence RDB(Redis DataBase) AOF(Append Of File) 在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就Snapshot 快照,恢复时将快照文件读到内存 RDB 及其执行流程 对上图的解读 具体流程如下: redis 客户端执行bgsave 命令或者自动触发bgsave 命令;

    2024年02月09日
    浏览(70)
  • redis 持久化机制

    client redis[内存] ----- 内存数据- 数据持久化--磁盘 Redis官方提供了两种不同的持久化方法来将数据存储到硬盘里面分别是: RDB 快照(Snapshot) AOF (Append Only File) 只追加日志文件 1 快照(Snapshot) 1. 特点 这种方式可以将某一时刻的所有数据都写入硬盘中,当然这也是 redis的默认开启持久

    2024年01月22日
    浏览(41)
  • Docker 持久化

    为了能够保存(持久化)数据以及共享容器间的数据, Docker 提出了 Volume 的概念。简单来说, Volume 就是目录或者文件,它可以 绕过 默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。 数据卷方式: 数据卷是一个特殊的文件或者目录,它将宿主机文件或

    2024年02月03日
    浏览(48)
  • Docker数据持久化

    在容器层的 UnionFS(联合文件系统)中对文件/目录的任何修改,无论是手工修改还是 容器在运行过程中的修改,在该容器丢失或被删除后这些修改将全部丢失。即这些修改是无 法保存下来的。若要保存下来这些修改,通常有两种方式: 定制镜像持久化:将这个修改过的容器

    2024年01月23日
    浏览(60)
  • 【iOS】—— 持久化

    快速展示,提升体验 已经加载过的数据,用户下次查看时,不需要再次从网络(磁盘)加载,直接展示给用户 节省用户流量(节省服务器资源) 对于较大的资源数据进行缓存,下次展示无需下载消耗流量 同时降低了服务器的访问次数,节约服务器资源。 离线使用 用户浏览

    2024年02月15日
    浏览(43)
  • Redis - 缓存持久化

    Redis 的缓存持久化有两种技术 : RDB 和 AOF Redis 的数据快照 简单说就是将缓存中的所有数据都记录到磁盘中,当Redis发生故障的时候,只需读取快照文件,就可恢复数据 相应的命令是 save 和 bgsave ,这两个命名都可以手动执行RDB持久化,不过 save 由 Redis 主线程来执行RDB,会阻

    2024年02月14日
    浏览(35)
  • redis-持久化-1

    RDB(Redis DataBase) AOF(Append Of File) 在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里 Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再

    2024年01月25日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包