首页 > 其他分享 >线段树的几种做法总结

线段树的几种做法总结

时间:2024-09-11 18:37:08浏览次数:1  
标签:总结 int 线段 几种 maxn include LL dp

线段树一些不太板的练手?

hdu单峰数列

权值线段树

hdu第x场1007

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
using namespace std;
#define LL long long
const int maxn=1e5+10;
int t[maxn*50],ls[maxn*50],rs[maxn*50];
int root,tot; 
LL a[maxn];
int sufmx[maxn],sufmn[maxn],dp[maxn];
void push_up(int x){
    t[x]=max(t[ls[x]],t[rs[x]]);
}
void upd(int &x,LL l,LL r,LL k,int id){
    if(!x)x=++tot;
    if(l==r){
        t[x]=id;
        return;
    }
    LL mid=(l+r)>>1;
    if(k<=mid) upd(ls[x],l,mid,k,id);
    else upd(rs[x],mid+1,r,k,id);
    push_up(x);
}
int que(int x,LL l,LL r,LL ql,LL qr){
    if(l>=ql&&r<=qr){
        return t[x];
    }
    int res=0;
    LL mid=(l+r)>>1;
    if(ql<=mid)res=max(res,que(ls[x],l,mid,ql,qr));
    if(qr>mid)res=max(res,que(rs[x],mid+1,r,ql,qr));
    return res;
}
void solve(){
    LL n,m,k;cin>>n>>m>>k; 
    root=0;    tot=0;
    for(int i=1;i<=n*50;i++)t[i]=0,ls[i]=0,rs[i]=0;
    t[0]=t[1]=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sufmx[i]=que(root,1,m,a[i],min(a[i]+k,m));
        sufmn[i]=que(root,1,m,max(0LL,a[i]-k),a[i]);
        //cout<<sufmx[i]<<' '<<sufmn[i]<<endl;
        upd(root,1,m,a[i],i);
    }
    int q;cin>>q;
    while(q--){
        int l,r;cin>>l>>r;
        int ans=0;
        for(int i=l;i<=r;i++)dp[i]=0;
        for(int i=l;i<=r;i++){
            dp[i]=1;
            if(sufmx[i]>=l)dp[i]=max(dp[i],dp[sufmx[i]]+1);
            if(sufmn[i]>=l)dp[i]=max(dp[i],dp[sufmn[i]]+1);
            ans=max(ans,dp[i]);
        }
        cout<<r+1-l-ans<<endl; 
    }
    
}
signed main() {
    int t;cin>>t;while(t--){
        solve();
    }
}

最值线段树(扫描线)

牛客有两题

含有复杂合并的线段树

结训赛题https://www.luogu.com.cn/problem/T497333?contestId=189707
“分享一种很方便的需要合并复杂信息的线段树写法,考虑将每个节点的信息存入结构体,并实现一个合并两个结构体并返回合并后的函数,则查询时仅需将先后查到的区间对应的结构体直接调用函数合并起来即可,hdu 第三场我就是用的这个写法,比大力讨论好写一万倍。”-luckyblock

#include<bits/stdc++.h>
#define ls(x) (x<<1)
#define rs(x) ((x<<1)+1)
#define mid ((l+r)>>1)
using namespace std;
int read(){
	char c=getchar();int f=1;int res=0;
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;c=getchar();
	}
	while(c>='0'&&c<='9'){
		res=res*10+c-'0';c=getchar();
	}
	return res*f;
}
const int maxn=2e5+10;
struct node{
	int cnt;
	bool is01,isl0,isr1;
}t[maxn*4],base[3]; 
int a[maxn];
node merge(const node &x,const node &y){
	node ret;
	if(!x.is01&&!y.is01){
		return base[2];
	}
	ret.cnt=x.cnt+y.cnt+(x.isr1&y.isl0);
	ret.is01=1;
	ret.isl0=x.is01?x.isl0:y.isl0;
	ret.isr1=y.is01?y.isr1:x.isr1;
	return ret;
}
int change(char x){
	if(x=='<')return 0;
	if(x=='(')return 1;
	return 2;
}
void build(int x,int l,int r){
	if(l==r){
		t[x]=base[a[l]];
		return;
	}
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	t[x]=merge(t[ls(x)],t[rs(x)]);
}
void modify(int x,int l,int r,int k){
	if(l==r){
		t[x]=base[a[k]];
		return;
	}
	if(k<=mid)modify(ls(x),l,mid,k);
	else modify(rs(x),mid+1,r,k);
	t[x]=merge(t[ls(x)],t[rs(x)]);
}
node query(int x,int ql,int qr,int l,int r){
	if(l>=ql&&r<=qr)return t[x];
	if (ql<=mid&&mid+1<=qr) {
		node ret1=query(ls(x),ql,qr,l,mid);
		node ret2=query(rs(x),ql,qr,mid+1,r);
		return merge(ret1,ret2);
	}
	if (ql<=mid) return query(ls(x),ql,qr,l,mid);
	return query(rs(x),ql,qr,mid+1,r);
}

signed main(){
	//0 < 1 ( 2 =
	base[0]=(node){0,1,1,0};
	base[1]=(node){0,1,0,1};
	base[2]=(node){0,0,0,0};
	int n,m;string s;
	cin>>n>>m>>s;
	for(int i=1;i<=n;i++){
		a[i]=change(s[i-1]);
	}
	build(1,1,n);
	while(m--){
		int x;cin>>x;
		if(x==1){
			cin>>x;char c;cin>>c;
			a[x]=change(c);
			modify(1,1,n,x);
		}
		else{
			int l,r;cin>>l>>r;
			cout<<query(1,l,r,1,n).cnt<<endl;
		}
	}
}

标签:总结,int,线段,几种,maxn,include,LL,dp
From: https://www.cnblogs.com/lyrrr/p/18408725

相关文章

  • 【企业知识库】文件备份的方法有哪几种?怎么操作?你真的知道吗?
    时至今日,文件备份已成为维护数据安全、保障业务连续性的关键一环。面对数据泄露、系统故障等潜在风险,文件备份不仅是合规性要求,更是企业稳健运营的基石。然而,许多企业对文件备份的方法和具体操作仍是知之甚少。本文将带大家一一揭开文件备份的迷团。一、文件备份的需求分析......
  • C# 控件的Tag的几种用法
    在C#中,Tag属性是一个非常灵活的特性,它允许开发者存储任意类型的数据到控件上。Tag属性广泛应用于WindowsForms、WPF以及其他基于控件的应用程序开发中。下面列举了几种Tag属性的常见用法:1.存储额外数据Tag属性可以用来存储与控件相关的额外信息,这些信息可能不是控......
  • 计算机网络知识点总结--适用于期末考试
    第一章 计算机网络概述1.计算机网络的类别1.1按分布范围分:广域网WAN,城域网MAN,局域网LAN, 个人区域网PAN1.2按使用者分:公用网,专用网1.3按交换技术分:电路交换报文交换分组交换1.4.按拓扑结构分:总线型,星型,环型,网状型1.5.按传输技术分:广播式网络 共享公共通信信......
  • LeetCode:2555. 两个线段获得的最多奖品 动态规划+滑动窗口
    2555.两个线段获得的最多奖品today2555两个线段获得的最多奖品题目描述在X轴上有一些奖品。给你一个整数数组prizePositions,它按照非递减顺序排列,其中prizePositions[i]是第i件奖品的位置。数轴上一个位置可能会有多件奖品。再给你一个整数k。你可以选择两......
  • VSCode 常用快捷键总结:涵盖编辑器操作、文件管理、查找替换、代码格式化、调试、视图
    编辑器操作光标与选择Ctrl+D:匹配当前选中的词汇或行,再次选中可操作。Alt+Click:在多个位置插入光标。Ctrl+Alt+↑/↓:在上下行插入光标。Shift+Alt+I:在选中范围内所有行结束符插入光标。Shift+Alt+(dragmouse):鼠标拖动区域,同时在多个行结束符插入光标。Ct......
  • 今天学习和总结
    学习了简单的算法知识排序中的快速排序,利用分治的思想来实现快速排序,对于前后大小有问题的进行swap的交换位置,这是基本的模版和源码includeusingnamespacestd;defineN1000100intA[N];voidquick_sort(inta,intb){if(a>=b)return;inti=a-1,j=b+1,x=A[a+b>>1];......
  • 达梦数据库 order by group by 同时使用的几种方式和注意事项
    在达梦数据库中,ORDERBY和GROUPBY可以同时使用,但有一些要点需要注意:使用方式基本用法:SELECTcolumn1,column2,COUNT(*)FROMtableGROUPBYcolumn1,column2ORDERBYcolumn1,COUNT(*);使用聚合函数排序:SELECTcolumn1,COUNT(*)FROMtableGROUPBYcolumn1ORDERBYC......
  • 线段树 transformation——hdu 4578
    问题描述:给定一个数列,数列中所有元素都初始化为0,对其执行多种区间操作操作1:add修改:对区间[L,R]内的所有数加c操作2:multi修改:对区间[L,R]内所有数乘以c操作3:change操作:把区间[L,R]内所有数改为c操作4:sum操作:对区间中的每个数的p次方求和。1<=p<=3输入:有不超过10个测试用例。......
  • KVM常问八股总结
    总结自用目录1.虚拟化技术概述2.为什么要用虚拟化?3.主流虚拟化方案3.1虚拟化技术主要分类3.2平台虚拟化技术分类3.3KVM虚拟化技术架构3.4KVM架构解析3.5KVM软件安装1.虚拟化技术概述虚拟化[Virtualization]技术最早出现在20世纪60年代的IBM大型机系统,在70年代的System370系列......
  • MySQL(六)查询连续出现N次问题总结
    连续问题的本质单调递增的等差数列例如游戏连续签到7天可以获得奖品,连续出现3次的数字求解方法(1)确定什么属性连续出现三次,即哪一属性连续,哪一属性相等(2)增加额外的等差递增列,然后进行作差分组案例查询至少连续出现3次的数字Logs表:idnum11213142......