博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷试炼场 提高模板-nlogn数据结构
阅读量:6935 次
发布时间:2019-06-27

本文共 5372 字,大约阅读时间需要 17 分钟。

 

树状数组-区间求和

P3374 【模板】树状数组 1

1 /*by SilverN*/ 2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 int read(){ 9 int x=0,f=1;char ch=getchar();10 while(ch<'0' || ch>'9'){
if(ch=='-')f=-1;ch=getchar();}11 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}12 return x*f;13 }14 const int mxn=500010;15 int n,m;16 int t[mxn];17 void add(int x,int v){18 while(x
树状数组1

 

树状数组-差分

P3368 【模板】树状数组 2

1 /*by SilverN*/ 2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 int read(){ 9 int x=0,f=1;char ch=getchar();10 while(ch<'0' || ch>'9'){
if(ch=='-')f=-1;ch=getchar();}11 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}12 return x*f;13 }14 const int mxn=500010;15 int n,m;16 int t[mxn];17 void add(int x,int v){18 while(x
树状数组2

 

线段树-区间加 区间乘

P3373 【模板】线段树 2

1 /*by SilverN*/  2 #include
3 #include
4 #include
5 #include
6 #include
7 #define ls l,mid,rt<<1 8 #define rs mid+1,r,rt<<1|1 9 #define lc rt<<1 10 #define rc rt<<1|1 11 using namespace std; 12 const int mxn=1000000; 13 long long n,p; 14 long long a[mxn]; 15 struct node{ 16 long long sum; 17 long long mu; 18 long long add; 19 }tr[mxn]; 20 void pushdown(int rt,int m){ 21 tr[lc].sum=(tr[lc].sum*tr[rt].mu+(m-(m>>1))*tr[rt].add)%p; 22 //m-(m>>1)得到区间范围的一半,也就是左子树的范围 23 tr[rc].sum=(tr[rc].sum*tr[rt].mu+(m>>1)*tr[rt].add)%p; 24 tr[lc].mu=tr[lc].mu*tr[rt].mu%p; 25 tr[rc].mu=tr[rc].mu*tr[rt].mu%p; 26 tr[lc].add=(tr[lc].add*tr[rt].mu+tr[rt].add)%p; 27 tr[rc].add=(tr[rc].add*tr[rt].mu+tr[rt].add)%p; 28 tr[rt].mu=1;tr[rt].add=0; 29 return; 30 } 31 void Build(int l,int r,int rt){ 32 tr[rt].mu=1;tr[rt].add=0; 33 if(l==r){ 34 tr[rt].sum=a[l]; 35 return; 36 } 37 int mid=(l+r)>>1; 38 Build(ls); 39 Build(rs); 40 tr[rt].sum=(tr[rt<<1].sum+tr[rt<<1|1].sum)%p; 41 return; 42 } 43 void add(int L,int R,int l,int r,int rt,int v){ 44 if(L<=l && r<=R){ 45 tr[rt].sum=(tr[rt].sum+v*(r-l+1))%p;//本身值累加区间新增值 46 tr[rt].add=(tr[rt].add+v)%p;//标记累加 47 return; 48 } 49 pushdown(rt,r-l+1);//下传 50 int mid=(l+r)>>1; 51 if(L<=mid)add(L,R,ls,v); 52 if(R>mid)add(L,R,rs,v); 53 tr[rt].sum=(tr[lc].sum+tr[rc].sum)%p; 54 return; 55 } 56 void multi(int L,int R,int l,int r,int rt,int v){ 57 if(L<=l && r<=R){ 58 tr[rt].add=(tr[rt].add*v)%p; 59 tr[rt].mu=(tr[rt].mu*v)%p; 60 tr[rt].sum=(tr[rt].sum*v)%p; 61 return; 62 } 63 pushdown(rt,r-l+1); 64 int mid=(l+r)>>1; 65 if(L<=mid)multi(L,R,ls,v); 66 if(R>mid)multi(L,R,rs,v); 67 tr[rt].sum=(tr[lc].sum+tr[rc].sum)%p; 68 return; 69 } 70 long long query(int L,int R,int l,int r,int rt){
//查询 71 if(L<=l && r<=R)return tr[rt].sum%p; 72 int mid=(l+r)>>1; 73 pushdown(rt,r-l+1); 74 long long res=0; 75 if(L<=mid)res=(res+query(L,R,ls))%p; 76 if(R>mid)res=(res+query(L,R,rs))%p; 77 tr[rt].sum=(tr[lc].sum+tr[rc].sum)%p; 78 return res%p; 79 } 80 int main(){ 81 int M; 82 scanf("%lld%lld%lld",&n,&M,&p); 83 int i,j; 84 for(i=1;i<=n;i++)scanf("%lld",&a[i]); 85 Build(1,n,1); 86 int op,g,t,c; 87 while(M--){ 88 scanf("%d%d%d",&op,&t,&g); 89 if(op==1){
//乘 90 scanf("%d",&c); 91 multi(t,g,1,n,1,c); 92 } 93 if(op==2){
//加 94 scanf("%d",&c); 95 add(t,g,1,n,1,c); 96 } 97 if(op==3){
//询问 98 long long ans=query(t,g,1,n,1); 99 printf("%lld\n",ans%p);100 }101 }102 return 0;103 }
线段树区间修改

 

二叉堆

P3378 【模板】堆

1 /*by SilverN*/ 2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 const int mxn=1200000; 9 int read(){10 int x=0,f=1;char ch=getchar();11 while(ch<'0' || ch>'9'){
if(ch=='-')f=-1;ch=getchar();}12 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}13 return x*f;14 }15 int tp[mxn];16 int cnt=0;17 void add(int x){18 tp[++cnt]=x;19 int now=cnt;20 while(now>1){21 int nxt=now/2;22 if(tp[nxt]<=tp[now])return;23 swap(tp[nxt],tp[now]);24 now=nxt;25 }26 return;27 }28 int del_head(){29 int res=tp[1];30 tp[1]=tp[cnt--];31 int now=1;32 while(now<=cnt/2){33 int nxt=now<<1;34 if(nxt
tp[nxt]){36 swap(tp[now],tp[nxt]);37 now=nxt;38 }39 else return res;40 }41 return res;42 }43 int main(){44 int n;45 n=read();46 int op,x,y;47 int i,j;48 for(i=1;i<=n;i++){49 op=read();50 switch(op){51 case 1:{x=read();add(x);break;}52 case 2:{printf("%d\n",tp[1]);break;}53 case 3:{del_head();break;}54 }55 }56 return 0;57 }
最小堆

 

此处是最小堆

转载于:https://www.cnblogs.com/SilverNebula/p/5910176.html

你可能感兴趣的文章
[USACO08FEB]酒店Hotel
查看>>
卫生纸效果,哈哈
查看>>
mysql导入excel数据
查看>>
Java中写入文件时换行符用"\r\n"、"\n"、"\r"?
查看>>
AIX 命令
查看>>
安装终端服务和终端服务授权,激活终端服务授权
查看>>
朋友,别在降低别人底线或被别人降低底线了!
查看>>
先考学历还是先提升能力?
查看>>
软件项目开发无成熟框架套路之成本代价
查看>>
设计模式(3)-装扮你的类(装饰模式)
查看>>
Android 数字签名学习笔记
查看>>
Linux下Gedit + Gmate ,实用的编辑器
查看>>
OO学习之二——面向对象分析(OOD)的介绍
查看>>
深入python3 (Dive Into Python 3) 在线阅读与下载
查看>>
linux 更改服务的启动顺序
查看>>
【数据结构】除去线性表中的重复数字
查看>>
[原]IE9 DOM的自定义属性问题
查看>>
[CLR via C#]17. 委托
查看>>
Android系统Google Maps开发实例浅析
查看>>
支持向量机(SVM)算法
查看>>