1:哈希

建立:拉链法:

a:数组

#include <bits/stdc++.h>

using namespace std;
const int md = 1e9;
int h[1000],idx,ne[1000],e[1000];
void add(int x)
{
int y = (x % md + md) % md;
e[idx] = x;
ne[idx] = h[y];
h[y] = idx ++;
}
int main()
{
memset(h,-1,sizeof h);
int n;
scanf("%d",&n);
add(n);
}

b:二维vector

2:字符串哈希

哈希函数 hash(s) = ((c1*pow(base,0)+c2*pow(base,1)+....+cn*pow(base,n-1))%p;

base 一般是大于ci的最大值,p和base都为质数且大于其给的范围,

同时可以用前缀和得到任意一段s的子串的哈希值

那么子串哈希hash(l,r) = (a[r] - a[l - 1] * base ^(r - l + 1) ) % p;

注意:为了防止偶然性可以用双哈希

3:对顶堆

所谓对顶堆,有点像双栈对顶那样,一个是小根堆,另一个是大根堆。假设 g  是大根堆,l是小根堆,两堆中间的元素,左边都是小于它的,且 g.top() 是小于它的最大值,右边都是大于它的,且 l.top() 是大于它的最小值

那么对顶堆是干嘛用的呢?

举一个例题:

给定N个数字,求其前ii个元素中第K小的那个元素。

我们很容易想到用堆来维护这个单调递增的序列,如果使用数组实现的话,我们直接输入数组下标为K的元素即可。但我们使用的是堆,它的实现方式——优先队列是不支持任意点访问的,那么我们就无法进行单点查询。引申对顶堆的概念,我们可以这样解决问题:

优先队列虽然不支持任意点访问,但可以用O(1)的时间查询出堆顶元素,也就是说,我们只能通过维护对顶堆中两个堆的堆顶元素来进行单调性的维护。怎么办呢?

原理很简单:根据数学中不等式的传递原理,假如一个集合A中的最小元素比另一个集合B中的最大元素还要大,那么就可以断定:A中的所有元素都比B中元素大。所以,我们把小根堆“放在”大根堆“上面”,如果小根堆的堆顶元素比大根堆的堆顶元素大,那么小根堆的所有元素要比大根堆的所有元素大。

回到这个问题:我们要求第K小的元素,那么我们把大根堆的元素个数限制成K个,前K个元素入队之后,每个元素在入队之前先与堆顶元素比较,如果比堆顶元素大,就加入小根堆,如果没有的话,把大根堆的堆顶弹出,将新元素加入大根堆。这样就维护出一个对顶堆。它的作用在于找出第K小的元素

同理,对顶堆还可以用于解决其他“第K小”的变形问题:比如求前i个元素的中位数等。

1:背包

Applese有1个容量为v的背包,有n个物品,每一个物品有一个价值ai,以及一个大小bi

然后他对此提出了自己的疑问,如果我不要装的物品装的价值最大,只是一定需要装m个物品,要使得求出来的物品价值的中位数最大
Applese觉得这个题依然太菜,于是他把这个问题丢给了你
当物品数量为偶数时,中位数即中间两个物品的价值的平均值

输入描述:

第一行三个数v, n, m,分别代表背包容量,物品数量以及需要取出的物品数量
接下来n行,每行两个数ai,bi,分别代表物品价值以及大小
n ≤ 1e5, 1 ≤ m ≤ n, ai ≤ 1e9, v ≤ 1e9, bi ≤ v

输出描述:

仅一行,代表最大的中位数

题解:

关于这道题,我们先来看看m是奇数怎么做。

很明显,我们可以考虑枚举中位数,然后判断其是否可行即可。这样,我们先对所有物品按价值从小到大排序。

那么,如果一个物品可以作为中位数,当前仅当存在一种方案,从这个物品的左边选m/2个物品,再从它右边选个物品,他们的容积和加上该物品的容积小于等于背包容积v。那么,我们明显只需要贪心去取,每次取最小的几个即可。

我们从i号点左/右取个物品的最小容积和。

对于这个,我们直接开个优先队列,使得优先队列的元素是当前最小的个元素即可。

那么,枚举i时,我们只需要判断下加上左右是否小于等于v,即可。

偶数

我们发现,其实,我们可以把它看做我们从左边的中位数的左边拿m/2--1个物品,再从右边的中位数的右边拿m/2个物品二分不断往右靠

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
struct Now{
ll vaule;
ll weight;
}a[100001];
bool cmp(Now a,Now b)
{
return a.vaule < b.vaule;
}
int s1[100001],s2[100001];
bool check(int res,int i,int v)
{
return s1[i - 1] + s2[res] + a[i].vaule <= v;
}
int main()
{
int v,n,m;
scanf("%d %d %d",&v,&n,&m);
for(int i = 1;i <= n; i ++)
{
scanf("%lld %lld",&a[i].vaule,&a[i].weight);
}
priority_queue<ll> q;
int x = m & 1;
m >>= 1;
sort(a + 1,a + n + 1,cmp);
for(int i = 1;i <= n; i ++)
{
q.push(a[i].weight);
s1[i] = s1[i - 1] + a[i].weight;
if(q.size() > m - 1 + x)
{
s1[i] -= q.top();
q.pop();
}
}
while(q.size())
q.pop();
for(int i =n; i >= 1;i --)
{
q.push(a[i].weight);
s2[i] = s2[i + 1] + a[i].weight;
if(q.size() > m)
{
s2[i] -= q.top();
q.pop();
}
}
if(x)
{
ll ans = 0;
for(int i = m + 1;i <= n - m;i ++)
{
if(s1[i-1] + s2[i + 1] + a[i].weight <= v)
ans = a[i].vaule;
}
printf("%lld\n",ans);
}
else{
ll ans = 0;
for(int i = m; i <= n- m; i ++)
{
ll l = i + 1,r = n-m + 1;
//int l=i+1,r=n-m+1;
while(l<=r){
int mid=l+r>>1;
if(s1[i-1]+s2[mid]+a[i].weight<=v)l=mid+1;
else r=mid-1;
}
if(r > i)
ans = max(ans,a[i].vaule + a[r].vaule);
}
printf("%lld\n",ans/2);
}
}

注意二分的边界,一个向上去取整一个向下取整。

2.小蜗的疑问

现在给你两个字符串a和b,a和b都由小写字母构成。

小蜗想知道字符串b在a中出现了几次(出现位置可以重叠)。

输入格式

第一行两个整数n,m,分别表示a和b的长度。

接下来两行,给出字符串a和b。

输出格式

输出一个数,表示答案

#include <bits/stdc++.h>

using namespace std;
const int base1 = 101,p = 9999971,base2 = 131,p1 = 9999973 ;
char a[200011],b[200011];
int ha[200011],hb[200011],c[200011],c1[200011],ha1[200001],hb1[200001];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
scanf("%s %s",a + 1,b + 1);
c[0] = 1;
c1[0] = 1;
for(int i = 1;i <= 200000; i ++)
{
c[i] = c[i - 1] * base1 %p;
c1[i] = c1[i - 1] * base2 % p1;
}
int res = 0;
for(int i = 1;i <= n;i ++)
{
ha[i] = (ha[i - 1] * base1 + a[i] - 'a' ) % p;
ha1[i] = (ha1[i - 1] * base2 + a[i] - 'a') % p1;
}
for(int i = 1;i <= m; i ++)
{
hb[i] = (hb[i - 1] * base1 + b[i] - 'a' ) % p;
hb1[i] = (hb1[i - 1] * base2 + b[i] - 'a') % p1;
} int ans = 0;
for(int i = 1;i + m - 1 <= n; i ++)
if((ha[i + m - 1]- 1LL * ha[i - 1] * c[m] % p + p ) % p == hb[m]
&& (ha1[i + m - 1] - 1LL * ha1[i - 1] * c1[m] % p1 + p1) % p1 == hb1[m])
{
ans ++;
}
printf("%d\n",ans);
}

3.动态中位数

中位数是按顺序排列的一组数据中居于中间位置的数。

现在依次给你nn个数a1,a2,…,an(保证n为奇数),你需要给出读入到第1,3,5,…,n 个数时,当前的中位数是多少。

输入格式

第一行一个整数n。

接下来一行共n个数。

输出格式

输出(n+1)/2个数,表示答案。

#include <bits/stdc++.h>

using namespace std;
int n;
priority_queue<int> q;
priority_queue<int ,vector<int> ,greater<int> > p;
int a[100010],b[100010],idx = 1;
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;i ++)
{
scanf("%d",&a[i]);
}
q.push(a[1]);
for(int i = 2;i <= n;i ++)
{
if(a[i] <= q.top())
q.push(a[i]);
else
p.push(a[i]);
if(q.size() - p.size() == 3)
p.push(q.top()),q.pop();
if(p.size() - q.size() == 1)
q.push(p.top()),p.pop();
if(i % 2 == 0)
printf("%d ",q.top());
}
printf("%d\n",q.top());
}

daimayuan第三课(哈希,堆)的更多相关文章

  1. 【C语言探索之旅】 第二部分第三课:数组

    内容简介 1.课程大纲 2.第二部分第三课: 数组 3.第二部分第四课预告:字符串 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语 ...

  2. 【C语言探索之旅】 第三课:你的第一个程序

    内容简介 1.课程大纲 2.第一部分第三课:你的第一个程序 3.第一部分第四课预告:变量的世界 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个 ...

  3. CodeIgniter框架入门教程——第三课 URL及ajax

    本文转载自:http://www.softeng.cn/?p=74 这节课讲一下CI框架的路由规则,以及如何在CI框架下实现ajax功能. 首先,先介绍CI框架的路由规则,因为CI框架是在PHP的基础 ...

  4. SQL初级第三课(下)

    我们续用第三课(上)的表 辅助表 Student                   Course               Score                    Teacher Sno ...

  5. shellKali Linux Web 渗透测试— 初级教程(第三课)

    shellKali Linux Web 渗透测试— 初级教程(第三课) 文/玄魂 目录 shellKali Linux Web 渗透测试—初级教程(第三课) 课程目录 通过google hack寻找测 ...

  6. 【第三课】ANR和OOM——贪快和贪多的后果(下)

    Out of Mana,法力耗尽. 内存就像法力,耗尽了就什么都不能做了.有时候一个应用程序占用了太大的内存,超过了Android系统为你规定的限制,那么系统就会干掉你,以保证其他app有足够的内存. ...

  7. 【第三课】ANR和OOM——贪快和贪多的后果(上)

    恼人的ANR 早先年用Android的时候,就连很多知名的app也总是莫名其妙崩溃,好像手机快的时候会崩溃,手机卡的时候app会卡死.卡死的时候会弹出来一个框,询问是要结束app还是继续等待.这就是A ...

  8. NeHe OpenGL教程 第三课:颜色渲染

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. BeagleBone Black 板第三课:Debian7.5系统安装和远程控制BBB板

    BBB板第三课:Debian7.5系统安装和远程控制BBB板 由于BBB板系统是Debian 7.4.据说使用Debian系统能够实现非常多BBB板的无缝连接.能够更好的学习和控制BBB板,所以就决定 ...

  10. 【Linux探索之旅】第二部分第三课:文件和目录,组织不会亏待你

    内容简介 1.第二部分第三课:文件和目录,组织不会亏待你 2.第二部分第四课预告:文件操纵,鼓掌之中 文件和目录,组织不会亏待你 上一次课我们讲了命令行,这将成为伴随我们接下来整个Linux课程的一个 ...

随机推荐

  1. noi 2.1基本算法之枚举

    7647:余数相同问题 1.描述 已知三个正整数 a,b,c. 现有一个大于1的整数x,将其作为除数分别除a,b,c,得到的余数相同. 请问满足上述条件的x的最小值是多少? 数据保证x有解. 2.输入 ...

  2. 微信小程序监听view到顶部的高度

    view style='width:100%;height:80rpx;' id='navigation'></view> wx.createSelectorQuery().sele ...

  3. Git 工作常用操作

    撤回commit 上一次提交的代码 git reset --soft HEAD^ HEAD^的意思是上一个版本,也可以写成HEAD~1 如果你进行了2次commit,想都撤回,可以使用HEAD~2 g ...

  4. JMeter压测基础(二)——Mysql数据库

    JMeter压测基础(二)Mysql数据库 环境准备 mysql驱动 JMeter jdbc配置 JMeter jdbc请求 1.下载mysql驱动:mysql-connector-java.jar ...

  5. 【C学习笔记】day2-1 给定两个整形变量的值,将两个值的内容进行交换

    #include<stdio.h> int main() { int a=0, b=1,temp; temp = b; b = a; a = temp; //printf("%d ...

  6. svn提交注释限制

    找到svn仓库 目录结构长这样 在hooks下的新建一个名字为pre-commit.bat的可执行文件 注意:findstr后边的.通配符表示一个任意字符,findstr "." ...

  7. laravel 内置auth()登录

    auth()命令 auth()->attempt()        登录验证 auth()->check        判断是否登录,有没有session缓存 auth()->log ...

  8. lnmp 修改MySQL默认密码

    wget http://soft.vpser.net/lnmp/ext/reset_mysql_root_password.sh;sh reset_mysql_root_password.sh 执行命 ...

  9. OpenStack 虚拟机制作qcow2格式镜像

    虚拟机拍摄快照导出1.将虚拟机制作成镜像(即拍摄快照):2.利用该虚机的快照,创建一个快照卷,大小是根据快照的大小自动设置的:3.利用命令将快照卷 upload-to-image 到虚机的快照内 ci ...

  10. jenkins +docker+python接口自动化之jenkins容器安装python3(二)

    前提是在docker下已经配置好jenkins容器了,是将python安装在jenkins容器下的 1.先看你的jenkins是否安装好 docker ps 2.以root权限进入jenkins容器: ...