ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022.7.27学习笔记

2022-07-27 20:31:27  阅读:140  来源: 互联网

标签:cnt 27 持久 int 笔记 leq 版本 2022.7 root


主要内容:

1.可持久化线段树
2.树状数组
3.倍增求LCA
4.树上差分
5.树链剖分:重链剖分、长链剖分
6.dfs和bfs基本应用
7.搜索的最优性、可行性、记忆化剪枝
8.迭代加深搜索
9.二进制搜索
10.折半搜索

(今天先介绍两种,因为其他八种本蒟蒻上课没听懂)

可持久化线段树

定义:

  可持久化线段树又被称为主席树。可持久化是指更新的同
时保留了历史版本,可以获得所有的历史版本。本质上是多颗线
段树,不过这些线段树共同使用了一部分枝干。

模板题:

P3919 【模板】可持久化线段树 1(可持久化数组)

题目背景

UPDATE : 最后一个点时间空间已经放大

2021.9.18 增添一组 hack 数据 by @panyf

标题即题意

有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集)

题目描述

如题,你需要维护这样的一个长度为 NN 的数组,支持如下几种操作

  1. 在某个历史版本上修改某一个位置上的值

  2. 访问某个历史版本上的某一位置的值

此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组)

输入格式

输入的第一行包含两个正整数 N, MN,M, 分别表示数组的长度和操作的个数。

第二行包含NN个整数,依次为初始状态下数组各位的值(依次为 a_iai​,1 \leq i \leq N1≤i≤N)。

接下来MM行每行包含3或4个整数,代表两种操作之一(ii为基于的历史版本号):

  1. 对于操作1,格式为v_i \ 1 \ {loc}_i \ {value}_ivi​ 1 loci​ valuei​,即为在版本v_ivi​的基础上,将 a_{{loc}_i}aloci​​ 修改为 {value}_ivaluei​

  2. 对于操作2,格式为v_i \ 2 \ {loc}_ivi​ 2 loci​,即访问版本v_ivi​中的 a_{{loc}_i}aloci​​的值,生成一样版本的对象应为vi

输出格式

输出包含若干行,依次为每个操作2的结果。

输入输出样例

输入 #1
5 10
59 46 14 87 41
0 2 1
0 1 1 14
0 1 1 57
0 1 1 88
4 2 4
0 2 5
0 2 4
4 2 1
2 2 2
1 1 5 91
#include<bits/stdc++.h>
#define mid ((l+r)>>1)
using namespace std;
struct chairman {
    int rt[1000001],T[20000001],L[20000001],R[20000001];
    int cnt;
    int build(int l,int r) {
        int root=++cnt;
        if(l==r) {
            scanf("%d",&T[root]);
            return root;
        }
        L[root]=build(l,mid);
        R[root]=build(mid+1,r);
        return root;
    }
    int update(int pre,int l,int r,int &x,int &c) {
        int root=++cnt;
        if(l==r) {
            T[root]=c;
            return root;
        }
        L[root]=L[pre];
        R[root]=R[pre];
        if(x<=mid)L[root]=update(L[pre],l,mid,x,c);
        else R[root]=update(R[pre],mid+1,r,x,c);
        return root;
    }
    void query(int pre,int l,int r,int& x) {
        if(l==r) {
            printf("%d\n",T[pre]);
            return;
        }
        if(x<=mid)query(L[pre],l,mid,x);
        else query(R[pre],mid+1,r,x);
    }
}ss; 
int main() {
    ss.cnt=0;
    int n,m;
    scanf("%d%d",&n,&m);
    ss.build(1,n);
    int v,cd,x,y;
    ss.rt[0]=1;
    for(int i=1; i<=m; ++i) {
        scanf("%d%d%d",&v,&cd,&x);
        if(cd==1) {
            scanf("%d",&y);
            ss.rt[i]=ss.update(ss.rt[v],1,n,x,y);
        }
        if(cd==2) {
            ss.rt[i]=ss.rt[v];
            ss.query(ss.rt[v],1,n,x);
        }
    }
    return 0;
}

折半搜索

类似于二分查找.

模板题:

P4799 [CEOI2015 Day2] 世界冰球锦标赛

题目描述

译自 CEOI2015 Day2 T1「Ice Hockey World Championship

今年的世界冰球锦标赛在捷克举行。Bobek 已经抵达布拉格,他不是任何团队的粉丝,也没有时间观念。他只是单纯的想去看几场比赛。如果他有足够的钱,他会去看所有的比赛。不幸的是,他的财产十分有限,他决定把所有财产都用来买门票。

给出 Bobek 的预算和每场比赛的票价,试求:如果总票价不超过预算,他有多少种观赛方案。如果存在以其中一种方案观看某场比赛而另一种方案不观看,则认为这两种方案不同。

输入格式

第一行,两个正整数 NN 和 M(1 \leq N \leq 40,1 \leq M \leq 10^{18})M(1≤N≤40,1≤M≤1018),表示比赛的个数和 Bobek 那家徒四壁的财产。

第二行,NN 个以空格分隔的正整数,均不超过 10^{16}1016,代表每场比赛门票的价格。

输出格式

输出一行,表示方案的个数。由于 NN 十分大,注意:答案 \le 2^{40}≤240。

输入输出样例

输入 #1
5 1000
100 1500 500 500 1000
输出 #1
8
#include<bits/stdc++.h>
#define ll long long
#define R register
#define N 55
using namespace std;
template<typename T>inline void read(T &a) {
    char c=getchar();
    T x=0,f=1;
    while(!isdigit(c)) {
        if(c=='-')f=-1;
        c=getchar();
    }
    while(isdigit(c)) {
        x=(x<<1)+(x<<3)+c-'0';
        c=getchar();
    }
    a=f*x;
}
ll n,m,w[N],mid,suma[1<<21],sumb[1<<21],cnta,cntb,ans;
inline void dfs(R int l,R int r,R ll sum,R ll a[],R ll &cnt) {
    if(sum>m)return;
    if(l>r) {
        a[++cnt]=sum;
        return;
    }
    dfs(l+1,r,sum+w[l],a,cnt);
    dfs(l+1,r,sum,a,cnt);
}
int main() {
    read(n);
    read(m);
    for(R int i=1; i<=n; i++)read(w[i]);
    mid=n>>1;
    dfs(1,mid,0,suma,cnta);
    dfs(mid+1,n,0,sumb,cntb);
    sort(suma+1,suma+1+cnta);
    for(R int i=1; i<=cntb; i++) ans+=upper_bound(suma+1,suma+1+cnta,m-sumb[i])-suma-1;
    printf("%lld\n",ans);
    return 0;
}

 后续我学会以后会将落下的补上

 

标签:cnt,27,持久,int,笔记,leq,版本,2022.7,root
来源: https://www.cnblogs.com/boranhoushen/p/16526208.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有