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

主席树学习

 很好的博客:https:blog.csdn.netqq_39809664articledetails79934516可持久化数组#include#inclu

 

很好的博客:https://blog.csdn.net/qq_39809664/article/details/79934516


可持久化数组

#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=1000000+10101;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int n,m,a[maxn],tree[maxn*20],rt[maxn*20],cnt,lc[maxn*20],rc[maxn*20];
//rt[i]为插入i个点后的树的根节点编号
void build(int &k,int l,int r){
k=++cnt;
if(l==r){tree[k]=a[l];return ;}
int mid=l+r>>1;
build(lc[k],l,mid);build(rc[k],mid+1,r);
return ;
}
void change(int &k,int pre,int l,int r,int q,int v){
k=++cnt;lc[k]=lc[pre];rc[k]=rc[pre];tree[k]=tree[pre];
if(l==r){tree[k]=v;return ;}
int mid=l+r>>1;
if(mid else change(lc[k],lc[pre],l,mid,q,v);
}
int query(int k,int l,int r,int pos){
if(l==r)return tree[k];
int mid=l+r>>1;
if(pos<=mid)return query(lc[k],l,mid,pos);
else return query(rc[k],mid+1,r,pos);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
build(rt[0],1,n);
for(int i=1;i<=m;i++){
int vi=read(),opt=read(),x=read();
if(opt==1)change(rt[i],rt[vi],1,n,x,read());
else printf("%d\n",query(rt[vi],1,n,x)),rt[i]=rt[vi];
}
return 0;
}

 


可持久化线段树 1(主席树)

#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=1000000+10101;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int len,n,m,a[maxn],b[maxn],cnt,rt[maxn*20];
struct wzq{
int sum,lr,rc;
}tre[maxn*20];
void build(int &k,int l,int r){
k=++cnt;
if(l==r)return ;
int mid=l+r>>1;
build(tre[k].lr,l,mid);build(tre[k].rc,mid+1,r);
return ;
}
void update(int l,int r,int &now,int pre,int pos){
tre[++cnt]=tre[pre];
now=cnt;
tre[cnt].sum++;
if(l==r)return ;
int mid=l+r>>1;
if(pos<=mid)update(l,mid,tre[now].lr,tre[pre].lr,pos);
else update(mid+1,r,tre[now].rc,tre[pre].rc,pos);
return ;
}
int query(int l,int r,int x,int y,int pos){
if(l==r)return l;
int xx=tre[tre[y].lr].sum-tre[tre[x].lr].sum;
int mid=l+r>>1;
if(xx>=pos)return query(l,mid,tre[x].lr,tre[y].lr,pos);
return query(mid+1,r,tre[x].rc,tre[y].rc,pos-xx);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read(),b[i]=a[i];
sort(a+1,a+n+1);
len=unique(a+1,a+1+n)-a-1;
build(rt[0],1,m);
for(int i=1;i<=n;i++){
int t=lower_bound(a+1,a+1+m,b[i])-a;
update(1,m,rt[i],rt[i-1],t);
}
for(int i=1;i<=m;i++){
int l=read(),r=read(),k=read();
printf("%d\n",a[query(1,m,rt[l-1],rt[r],k)]);
}
return 0;
}

 


[CQOI2015]任务查询系统

这道题可以对每秒建棵权值线段树,并以1~lim(优先级的最大值)为区间大小记录个数,这样就可以处理在x秒的第k小前缀和了,

但是lim因为很大,可能会导致MLE,所以要离散化一下

// luogu-judger-enable-o2
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=201010;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int n,m,cnt,tot,rt[maxn],to[maxn],h[maxn];
ll ans=1;
struct wzq{ll sum;int sz,lr,rc;}tre[maxn*128];
struct hhh{int pos,v;}b[maxn];
bool cmp(hhh i,hhh j){return i.posvoid build(int &k,int l,int r){
k=++cnt;
if(l==r)return ;
int mid=l+r>>1;
build(tre[k].lr,l,mid);build(tre[k].rc,mid+1,r);
return ;
}
void change(int &k,int pre,int l,int r,int tag){
k=++cnt;
tre[k]=tre[pre];tre[k].sum+=tag;
if(tag<0)tre[k].sz--;
else tre[k].sz++;
if(l==r)return ;
int mid=l+r>>1;
if(abs(tag)<=h[mid])change(tre[k].lr,tre[pre].lr,l,mid,tag);
else change(tre[k].rc,tre[pre].rc,mid+1,r,tag);
return ;
}
ll query(int k,int l,int r,int pos){
if(l==r)return 1ll*tre[k].sum/tre[k].sz*min(pos,tre[k].sz);
int mid=l+r>>1;
if(tre[tre[k].lr].sz>=pos)return 1ll*query(tre[k].lr,l,mid,pos);
return 1ll*tre[tre[k].lr].sum+query(tre[k].rc,mid+1,r,pos-tre[tre[k].lr].sz);
}
int main(){
m=read();n=read();
for(int i=1;i<=m;i++){
int x=read(),y=read(),z=read();
b[++tot].pos=x;b[tot].v=z;
b[++tot].pos=y+1;b[tot].v=-z;
h[i]=z;
}
sort(h+1,h+m+1);
int tot1=unique(h+1,h+m+1)-h-1;
sort(b+1,b+tot+1,cmp);build(rt[0],1,tot1);
for(int i=1;i<=tot;i++)change(rt[i],rt[i-1],1,tot1,b[i].v);
for(int i=tot;i>=1;i--)if(b[i].pos!=b[i+1].pos)to[b[i].pos]=i;
for(int i=1;i<=m;i++)if(!to[i])to[i]=to[i-1];
for(int i=1;i<=n;i++){
ll x=read(),a=read(),b=read(),c=read();
ll k=(1ll*a*ans+b)%c+1;
x=rt[to[x]];
if(tre[x].sz<=k)ans=1ll*tre[x].sum;
else ans=query(x,1,tot1,k);
printf("%lld\n",ans);
}
return 0;
}

 


推荐阅读
  • 下面是一个用openssl实现获取https网页内容的demo,整个流程比较简单,主要封装的API如下staticinthttps_init(http ... [详细]
  • 3357: [Usaco2004]等差数列
    3357:[Usaco2004]等差数列TimeLimit:10SecMemoryLimit:128MBSubmit:321Solved:153[Submit][Status][D ... [详细]
  • 原文链接https://www.cnblogs.com/zhouzhendong/p/9161514.html ... [详细]
  • 编译原理c语言词法分析器,用C语言实现一个真正的词法分析器
    词法分析,是编译器的第一个模块,也是最简单的模块。最简单,指的是相对于编译器这种大型程序而言,与一般的代码相比还是有点复杂的 ... [详细]
  • [USACO 2006 November Gold] 玉米地Corn Fields
    题目描述  FarmerJohn新买了一块长方形的牧场,这块牧场被划分成M行N列(1<M<12;1<N<12),每一格都是一块正方形的土地。FJ打 ... [详细]
  • github:https:github.comfroghuiyolandaIO模型和多线程模型实现多线程设计的几个考虑在我们的设计中,mainre ... [详细]
  • 在ROS系统中,参数读写一般通过xml或者yaml格式的文件,其中yaml用得比较多。这是一种可读性高,轻量级的标记语言,简单好用。对于yaml文件,ros中用的较早版本的yaml- ... [详细]
  • flash代码_正点原子【STM32F407探索者】第三十九章 FLASH 模拟 EEPROM 实验
    1)资料下载:点击资料即可下载2)对正点原子Linux感兴趣的同学可以加群讨论:9354467413)关注正点原子公众号,获取最新资料更新 ... [详细]
  • 九日集训 Day 4 指针
    一、概念定义1、指针即地址计算机中所有的数据都必须放置在内存中,不同类型的数据占用的字节数也不一样,例如32位整型int占据4个字节,64位整型longlong占据8个字节,字符型 ... [详细]
  • 最近自己做一个工具最后涉及到一个存储成bmp位图的形式,由于这部分并不是整个project的重点我就从网上找了例子改了改,但是目前的问题是有很多时候都是存储的bmp全黑,我也并不知道是怎么回事。 ... [详细]
  • DFS基本概念步骤优缺点典型例题递推基本概念直接或者间接调用自身的算法称为递归算法一般数据n ... [详细]
  • 找出字符串中重复字符
    2019独角兽企业重金招聘Python工程师标准packagejavaBasic;importjava.util.HashMap;importjava.util.Map; ... [详细]
  • 题意给出一个长度为n的序列,有一些位置可以放任意的数,问最长上升序列的长度。n ... [详细]
  • IDEA实用插件Lombok
    LombokLombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。通常,我们所定义的对象和b ... [详细]
  • 字符串匹配: BF与KMP算法
    文章目录一.BF算法1.算法思想2.代码实现二.KMP算法1.算法思想概述2.理解基于最长相等前后缀进行匹配3.代码中如何实现next数组5.代码实现6.next数组的优化一.BF ... [详细]
author-avatar
黑暗中的数字
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有