当前位置: 首页 > wzjs >正文

做网站的模版seo优化工具软件

做网站的模版,seo优化工具软件,网页小游戏单机,济南竞价托管前言 今天给大家带来两道贡献法的问题,先来讲一下什么是贡献法。 贡献法,与其说是一种算法,不如说是一种数学方法,是一种思维方式。 先来给大家举个例子,假设现在有个问题,需要你在一个只有小写字母的字…

前言

今天给大家带来两道贡献法的问题,先来讲一下什么是贡献法

贡献法,与其说是一种算法,不如说是一种数学方法,是一种思维方式

先来给大家举个例子,假设现在有个问题,需要你在一个只有小写字母的字符串中查找所有仅包含一个字符a子串数量

暴力的话是枚举所有子串,O(n^2)显然不符合我们的预期,那么有什么方法优化呢?

这就要用到我们今天要讲的贡献法了,这一种横看成岭侧成峰的算法,我们来观察下面的样例。

bbbbbacccc

可以发现在中间位置出现了a,我们将a的左右两侧划分出来。

bbbbb|a|cccc

问题就转化成了在a左边选一个字母,同时在a右边选一个字母的所有选法。

我们设左边的字符数量为left,右边的字符数量为right,那么根据排列组合的知识可以得到子串数量为:

(left + 1) * (right + 1)

注意这里要加一因为a也要算进去。

以上就是贡献法的大致思路,所谓横看成岭侧成峰,就是从结果出发,逆推出有效的结论

可能有的小伙伴发现了我们这个题目有一个要求,即——仅包含一个字符a

那我们就来想一下,如果没有这个条件,贡献法可不可行呢?

答案是否定的,我们来观察下面的序列

bbbbabbabbb

可以明显的发现最长的串是同时包含两个a的,而我们使用贡献法就需要分别求出包含指定a的所有子串,我们将这些子串视为一个集合

在计算完所有包含指定的a的所有子串后我们要进行集合合并,而根据容斥原理,集合合并时需要减去两个集合的交集,显然这个交集我们是不好求出来的。

造成这种情况的原因就是两个集合不是互斥的,放在概率论中就可以说两个条件不是独立的

所以在判断能否使用贡献法之前需要先判断一下给定的条件能否使每个元素的贡献皆相互独立

反之,如果发现条件能够使整个结果的集合划分为几个部分,那么就可以使用贡献法。(反应在题目中一般就是“唯一”,“单个”等词)

纸上学来终得钱,接下来我们就根据具体的题目分析,一起来看看所谓的“贡献法”到底有何魔力。


孤独的照片


分析

暴力枚举所有区间的话时间复杂度是O(n^2),显然行不通,但是我们发现所有的孤独的照片都有一个特点,即——同时包含两种牛,并且其中有一种牛的数量为1

很敏锐的发现题目中有唯一的条件,那么可不可以用我们上面讲的贡献法来写呢?

使用贡献法需要满足一个条件,即——我们选定的贡献的对象可以将要求的集合划分

很显然是可以的,因为两头可能孤独的牛不会出现在同一张“孤独的照片”内所以任意两头牛产生的贡献的交集为空集,所以我们可以使用贡献法。

那么接下来我们就来思考一下如何使用贡献法。

根据上面的思路,我们需要通过排列组合来每头牛的贡献就要保证当前区间只有一头此类牛。

这个简单,我们预处理出每头牛左边和右边的同类牛的位置(使用扫描法),就可以计算出对于每头牛的最长的“孤独的照片”,随后进行排列组合就好了。

这道题排列组合有一个小技巧,因为有一个要求最短区间长度为3,所以我们需要分类讨论该位置在区间两边和在区间中间的情况。


代码

/*贡献法
*/
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N = 500010;
char s[N];
int n;
int l[N], r[N];
LL ans;LL find(char x)
{int m = 0;memset(l, 0, sizeof(l)); memset(r, 0, sizeof(r));for(int i = 1; i <= n; i++)if(s[i] == x)l[i] = m, m = i;m = n + 1;for(int i = n; i >= 1; i--)if(s[i] == x)r[i] = m, m = i;// 预处理LL ls = 0;for(int i = 1; i <= n; i++){if(s[i] == x) //匹配了{int left = i - l[i] - 1, right = r[i] - i - 1; //左右长度//printf("%d %d %d ", i, left, right);ls += max((LL)0, (LL)left * right);ls += max(0, left - 1);ls += max(0, right - 1);}}return ls;
}int main()
{scanf("%d%s", &n, s + 1);ans += find('G');ans += find('H');printf("%lld", ans);return 0;
}

子串分值


分析

可以发现题目中有唯一的要求,所以我们考虑使用贡献法

那么,接下来我们要如何来划分呢?

这个简单,我们通过26个英文字母来划分,因为f函数是求贡献和,所以我们每次只求单个字符的贡献,最后加起来就一定是贡献和。

但是如果这道题是要我们判断区间内存在个数为1的字符的区间的数量,显然就无法直接用贡献法求解了,需要进一步的分析。


代码

// 贡献法,枚举26个字母,贡献求和
#include<iostream>
using namespace std;
typedef long long LL;
const int N = 100010;
char s[N];
int n, l[N], r[N];
LL idx;
LL find(char x)
{int m = 0; LL idx = 0;for(int i = 1; i <= n; i++)if(s[i] == x)l[i] = m, m = i;m = n + 1;for(int i = n; i >= 1; i--)if(s[i] == x)r[i] = m, m = i;for(int i = 1; i <= n; i++){if(s[i] == x){int left = i - l[i] - 1, right = r[i] - i - 1;idx += ((LL)left + 1) * (right + 1);}}return idx;
}int main()
{scanf("%s", s + 1);for(int i = 1; s[i]; n = i++);for(char x = 'a'; x <= 'z'; x++)idx += find(x);printf("%lld", idx);return 0;
}

http://www.dtcms.com/wzjs/317236.html

相关文章:

  • 大连 网站制作 外贸酒吧营销用什么软件找客源
  • 效果好企业营销型网站建设网页设计成品源代码
  • 网站的关键词推扩是怎样做百度网盘app官网
  • 医院网站怎么做优化排名企业培训内容有哪些
  • 谁能帮我做网站seo百度关键词优化软件
  • 团队展示网站人民日报今日新闻
  • 高端企业网站建设费用南昌百度seo
  • 酒店网站可以怎么做杭州seo俱乐部
  • 营销型网站建设报价方案goole官网
  • 抚州网站制作企业软文
  • 临沂集团网站建设抖音怎么运营和引流
  • 湖南网站建设开发百度站内搜索的方法
  • 建网站靠什么赚钱品牌策划公司
  • 晋城市网站建设网站排名监控工具
  • 网站建设思路方案网络营销怎么推广
  • 新乡市做网站直销系统网站百度seo查询系统
  • 个人免费网站建设模板郑州网站优化外包
  • wordpress 12张表seo标签优化
  • 2023一般纳税人企业所得税怎么算兰州网站seo优化
  • 网站空间管理平台关键词优化和seo
  • 专业网站建设技术北京搜索引擎推广服务
  • 网站点击量设计软件开发自学步骤
  • wordpress 获取置顶文章佛山seo技术
  • 鞍山做网站哪家好seo技术培训学校
  • 建设网站简单的需要多少天杭州seo俱乐部
  • 竞价广告是怎么推广的长沙竞价优化
  • 网站建设的课程搜索到的相关信息
  • 顺德企业网站制作天津网站快速排名提升
  • 企业定制网站价格表如何推广宣传一个品牌
  • 苏州cms模板建站宝深圳seo推广