洛谷 CF896C Willem, Chtholly and Seniorious之珂朵莉树板子

news/2024/11/16 13:22:28/文章来源:https://www.cnblogs.com/qc0817/p/18352184

洛谷CF896C题解


传送锚点


摸鱼环节

Willem, Chtholly and Seniorious

题面翻译

【题面】
请你写一种奇怪的数据结构,支持:

  • \(1\) \(l\) \(r\) \(x\) :将\([l,r]\) 区间所有数加上\(x\)
  • \(2\) \(l\) \(r\) \(x\) :将\([l,r]\) 区间所有数改成\(x\)
  • \(3\) \(l\) \(r\) \(x\) :输出将\([l,r]\) 区间从小到大排序后的第\(x\) 个数是的多少(即区间第\(x\) 小,数字大小相同算多次,保证 \(1\leq\) \(x\) \(\leq\) \(r-l+1\) )
  • \(4\) \(l\) \(r\) \(x\) \(y\) :输出\([l,r]\) 区间每个数字的\(x\) 次方的和模\(y\) 的值(即(\(\sum^r_{i=l}a_i^x\) ) \(\mod y\) )

【输入格式】
这道题目的输入格式比较特殊,需要选手通过\(seed\) 自己生成输入数据。
输入一行四个整数\(n,m,seed,v_{max}\) ($1\leq $ \(n,m\leq 10^{5}\) ,\(0\leq seed \leq 10^{9}+7\) $,1\leq vmax \leq 10^{9} $ )
其中\(n\) 表示数列长度,\(m\) 表示操作次数,后面两个用于生成输入数据。
数据生成的伪代码如下

其中上面的op指题面中提到的四个操作。

【输出格式】
对于每个操作3和4,输出一行仅一个数。

题目描述

— Willem...

— What's the matter?

— It seems that there's something wrong with Seniorious...

— I'll have a look...

Seniorious is made by linking special talismans in particular order.

After over 500 years, the carillon is now in bad condition, so Willem decides to examine it thoroughly.

Seniorious has $ n $ pieces of talisman. Willem puts them in a line, the $ i $ -th of which is an integer $ a_{i} $ .

In order to maintain it, Willem needs to perform $ m $ operations.

There are four types of operations:

  • $ 1\ l\ r\ x $ : For each $ i $ such that $ l<=i<=r $ , assign $ a_{i}+x $ to $ a_{i} $ .
  • $ 2\ l\ r\ x $ : For each $ i $ such that $ l<=i<=r $ , assign $ x $ to $ a_{i} $ .
  • $ 3\ l\ r\ x $ : Print the $ x $ -th smallest number in the index range $ [l,r] $ , i.e. the element at the $ x $ -th position if all the elements $ a_{i} $ such that $ l<=i<=r $ are taken and sorted into an array of non-decreasing integers. It's guaranteed that $ 1<=x<=r-l+1 $ .
  • $ 4\ l\ r\ x\ y $ : Print the sum of the $ x $ -th power of $ a_{i} $ such that $ l<=i<=r $ , modulo $ y $ , i.e. .

输入格式

The only line contains four integers $ n,m,seed,v_{max} $ ( $ 1<=n,m<=10{5},0<=seed<10+7,1<=vmax<=10^{9} $ ).

The initial values and operations are generated using following pseudo code:

def rnd():ret = seedseed = (seed * 7 + 13) mod 1000000007return retfor i = 1 to n:a[i] = (rnd() mod vmax) + 1for i = 1 to m:op = (rnd() mod 4) + 1l = (rnd() mod n) + 1r = (rnd() mod n) + 1if (l > r): swap(l, r)if (op == 3):x = (rnd() mod (r - l + 1)) + 1else:x = (rnd() mod vmax) + 1if (op == 4):y = (rnd() mod vmax) + 1

Here $ op $ is the type of the operation mentioned in the legend.

输出格式

For each operation of types $ 3 $ or $ 4 $ , output a line containing the answer.

样例 #1

样例输入 #1

10 10 7 9

样例输出 #1

2
1
0
3

样例 #2

样例输入 #2

10 10 9 9

样例输出 #2

1
1
3
3

提示

In the first example, the initial array is $ {8,9,7,2,3,1,5,6,4,8} $ .

The operations are:

  • $ 2\ 6\ 7\ 9 $
  • $ 1\ 3\ 10\ 8 $
  • $ 4\ 4\ 6\ 2\ 4 $
  • $ 1\ 4\ 5\ 8 $
  • $ 2\ 1\ 7\ 1 $
  • $ 4\ 7\ 9\ 4\ 4 $
  • $ 1\ 2\ 7\ 9 $
  • $ 4\ 5\ 8\ 1\ 1 $
  • $ 2\ 5\ 7\ 5 $
  • $ 4\ 3\ 10\ 8\ 5 $

一股浓浓的二次元oier味,是的,这是珂朵莉树的模板。

正片开始

珂朵莉树用于在数据随机的情况下处理区间平铺问题非常给力,可以用堆维护,结构体储存信息。

#define IT set<node>::iterator

1.维护信息

用结构体维护珂朵莉树各区间的信息。

code:

struct node
{ll l,r;mutable ll v;node(ll l,ll r=0,ll v=0):l(l),r(r),v(v){}bool operator<(const node &o) const{return l<o.l;}
};

2.关键 · 分离操作

利用指针将树的区间进行分割,此时分成三种情况,具体实现见代码。

code:

IT split(int pos)
{IT it=s.lower_bound(node(pos));//获得指针if(it!=s.end()&&it->l==pos) return it;//如果指针在开头,则直接返回it--;if(it->r<pos) return s.end();//pos过大,返回endll l=it->l,r=it->r,v=it->v;s.erase(it);//清空原位置 s.insert(node(l,pos-1,v));//更新return s.insert(node(pos,r,v)).first;
}

2.区间增加

用指针指向区间左右端,对区间值增加即可。

code:

void add(ll l,ll r,ll val)
{IT itr=split(r+1),itl=split(l);//寻找左右端点for(IT it=itl;it!=itr;++it) it->v+=val;
}

3.区间铺平

分离后清空,直接搞。

code:

void assign_val(ll l,ll r,ll val)
{IT itr=split(r+1),itl=split(l);s.erase(itl,itr);//清空区间s.insert(node(l,r,val));//覆盖修改
}

4.查询区间第k小。

缓存下区间,排完序后直接搞。

code:

struct RANK
{ll num,cnt;bool operator<(const RANK &a) const{return num<a.num;}RANK(ll num,ll cnt):num(num),cnt(cnt){}
};//缓存信息
ll ranks(ll l,ll r,ll k)
{IT itr=split(r+1),itl=split(l);vector<RANK> vp;for(IT i=itl;i!=itr;++i){vp.push_back(RANK(i->v,i->r - i->l+1));}sort(vp.begin(),vp.end());//排序找第k小int i;for(i=0;i<vp.size();++i){if(vp[i].cnt<k){k-=vp[i].cnt;}else {break;}}return vp[i].num;
}

5.区间数字\(x\)次方和。

很明显得用快速幂。

code:

ll pown(ll a,ll b,ll mod)
{ll res=1;ll ans=a%mod;while(b){if(b&1) {res=res*ans%mod;}ans=ans*ans%mod;b>>=1;}return res;
}

暴力枚举区间值,把区间丢入快速幂,后乘区间长度,并统计答案即可。

code:

ll sum(ll l,ll r,ll e,ll mod)
{IT itr=split(r+1),itl=split(l);ll res=0;for(IT i=itl;i!=itr;++i)res=(res+pown(i->v,e,mod)*(i->r - i->l+1)%mod)%mod;//利用快速幂计算区间数值的x次方并乘上区间长度,再相加return res;
}

注意 · 注意!!!

在进行分离操作时,一定要先右后左,如果先处理\(itl\),再处理\(itr\)时,原指向\(itl\)的地方会被清空掉,此时再调用s.erase就会RE。

同时由于数据随机,所以RE是概率发生,此时就是RP大比拼时刻了.


完整代码

#include<bits/stdc++.h>
#define IT set<node>::iterator
using namespace std;
typedef long long ll;
const ll MOD= 1e9+7;
const ll N=1e5+5;struct node
{ll l,r;mutable ll v;node(ll l,ll r=0,ll v=0):l(l),r(r),v(v){}bool operator<(const node &o) const{return l<o.l;}
};
ll n,m,seed,vmax,a[N];
set<node>s;
IT split(int pos)
{IT it=s.lower_bound(node(pos));if(it!=s.end()&&it->l==pos) return it;it--;if(it->r<pos) return s.end();ll l=it->l,r=it->r,v=it->v;s.erase(it);s.insert(node(l,pos-1,v));return s.insert(node(pos,r,v)).first;
}
void add(ll l,ll r,ll val)
{IT itr=split(r+1),itl=split(l);for(IT it=itl;it!=itr;++it) it->v+=val;
}
void assign_val(ll l,ll r,ll val)
{IT itr=split(r+1),itl=split(l);s.erase(itl,itr);s.insert(node(l,r,val));
}
struct RANK
{ll num,cnt;bool operator<(const RANK &a) const{return num<a.num;}RANK(ll num,ll cnt):num(num),cnt(cnt){}
};
ll ranks(ll l,ll r,ll k)
{IT itr=split(r+1),itl=split(l);vector<RANK> vp;for(IT i=itl;i!=itr;++i){vp.push_back(RANK(i->v,i->r - i->l+1));}sort(vp.begin(),vp.end());int i;for(i=0;i<vp.size();++i){if(vp[i].cnt<k){k-=vp[i].cnt;}else {break;}}return vp[i].num;
}
ll pown(ll a,ll b,ll mod)
{ll res=1;ll ans=a%mod;while(b){if(b&1) {res=res*ans%mod;}ans=ans*ans%mod;b>>=1;}return res;
}
ll sum(ll l,ll r,ll e,ll mod)
{IT itr=split(r+1),itl=split(l);ll res=0;for(IT i=itl;i!=itr;++i)res=(res+pown(i->v,e,mod)*(i->r - i->l+1)%mod)%mod;return res;
}
ll rnd()
{ll ret=seed;seed=(seed*7+13)%MOD;return ret;}
int main()
{cin>>n>>m>>seed>>vmax;for(int i=1;i<=n;++i){a[i]=(rnd()%vmax)+1;s.insert(node(i,i,a[i]));}for(ll i=1;i<=m;++i){ll op,l,r,x,y;op=(rnd()%4)+1;l=(rnd()%n)+1;r=(rnd()%n)+1;if(l>r) swap(l,r);if(op==3){x=(rnd()%(r-l+1))+1;}else{x=(rnd()%vmax)+1;}if(op==4) {y=(rnd()%vmax)+1;}if(op==1) add(l,r,x);else if(op==2) assign_val(l,r,x);else if(op==3) cout<<ranks(l,r,x)<<endl;else cout<<sum(l,r,x,y)<<endl;}return 0;
}

完结收工!!!!!

个人主页

看完点赞,养成习惯

\(\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/780816.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

制作计算器——训练程序思维

自己做的计算器主要的逻辑如下:用两个集合,每个数字对应一个符号,先收集数字和符号,然后再处理乘除法,再处理加减法,最后得出计算的数字;(此方法不一定是最优方法,因为没有收集网络上的资料,是自己想出来的解决方案)按钮 “=” 的逻辑如下:var val = show.Text;var…

全新在线客服系统源码(pc+h5+uniapp+公众号小程序+抖音)附搭建接入教程

全新在线客服系统源码介绍 一、系统概述与优势 本系统是一款基于PHP的开源在线客服系统,支持PC端、移动端(小程序)、H5页面以及Uniapp多端接入。系统利用网络技术和人工智能技术,实现用户与客服人员的即时聊天沟通,有效提升服务质量和用户满意度。系统优势包括提高服务效率…

抖音私信客服系统 - 对接抖音私信统一接待回复 -以及私信或评论自动回复

在数字化时代,企业面临着前所未有的挑战与机遇。社交媒体的快速发展,尤其是小红书和抖音这样的平台,为企业提供了与消费者沟通和营销的新渠道。本文将探讨全渠道私信客服系统在企业转型中的重要性和独特价值。 一、小红书与抖音的崛起小红书以其精准的内容分享和消费推荐功能…

GitLab 之 Git LFS 大文件存储的配置

参考 https://cloud.tencent.com/developer/article/1010589LFS介绍 Git 大文件存储(Large File Storage,简称LFS)目的是更好地把大型二进制文件,比如音频文件、数据集、图像和视频等集成到 Git 的工作流中。我们知道,Git 存储二进制效率不高,因为它会压缩并存储二进制文…

lg-dp3

lg-dp3 计数的东西有什么特点、转化/好的刻画方式 A Farthest City题面关键信息:权值为1的最短路 --- bfs --- 分层那么显然加一个点他只能与上一层连,和一层内部连。则设 \(f_{i,j}\) 为 [点数,最后一层点数] 有 \[f_{i,j}=2^{j\choose 2}\sum_{k=1}^{i-j}{f_{i-j,k}(2^k-1…

FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流

​SRT Streamer是一个安卓手机端的开源SRT协议直播推流框架,可用于RTMP直播和SRT直播。SRT Streamer支持的视频编码包括H264、H265等等,支持的音频编码包括AAC、OPUS等等,可谓功能强大的APP直播框架。相比之下,另一款APP直播框架RTMP Streamer支持RTMP直播和RTSP直播,不支…

mongo变更流使用及windows下副本集五分钟搭建

mongodb的变更流解释: 变更流(Change Streams)允许应用程序访问实时数据变更,从而避免事先手动追踪 oplog 的复杂性和风险。应用程序可使用变更流来订阅针对单个集合、数据库或整个部署的所有数据变更,并立即对它们做出响应。由于变更流采用聚合框架,因此,应用程序还可对…

ConcurrentHashMap的原理

背景 我们知道hashmap是一个线程不安全的数据结构,在多线程编程的时候,多个线程同时向hashmap中put元素的时候,会发生数据丢失。多线程put操作后,再get操作导致死循环。 多线程put非NULL元素后,get操作得到NULL值。 使用 为了保证并发安全,我们使用hashmap的时候,建议是…

ABC201E Xor Distances 题解

从洛谷搬过来的题解,因为感觉和上一把 ABC的E有点像呐ABC201E Xor Distances 题解 题目大意 给定一个带权树,求树上每两点的简单路径上的边权的异或和的和。 形式化的,定义 \(dis(i,j)\) 为 \(i\) 到 \(j\) 的简单路径上的边权的异或和,求 \(\large\sum\limits_{i=1}^n\sum…

学生Java学习路程-6

ok,到了一周一次的总结时刻,我大致会有下面几个方面的论述:1.这周学习了Java的那些东西2.这周遇到了什么苦难3.未来是否需要改进方法等几个方面阐述我的学习路程。 复习面向对象数组 数组的三种初始化方法:默认,静态,动态引用类型Man放入数组中的测试代码数组的拷贝 使用…

Lazysysadmin靶机笔记

Lazysysadmin靶机笔记 概述 lazysysadmin是一台Vulnhub靶机,整体比较简单,要对一些存在服务弱口令比较敏感。 靶机地址:https://pan.baidu.com/s/19nBjhMpGkdBDBFSnMEDfOg?pwd=heyj 提取码:heyj 一、nmap扫描 1、主机发现 # -sn只做ping扫描,不做端口扫描 sudo nmap -sn 1…