复杂度

最大团模版

こ雲淡風輕ζ 提交于 2020-03-01 08:33:40
复 杂 度 O ( 3 m 3 ) 复杂度O(3^{\frac{m}{3}}) 复 杂 度 O ( 3 3 m ​ ) int n,m; //m为节点个数 int mpp[50][50]; int st[50][50]; int mans=0; int dp[50]; //dp[i] 表示为i到m的节点中最大团的节点数 map<string,int> mp; void dfs(int stp,int num){ if(!num){ if(stp>mans){ mans=stp; } return; } for(int i=0;i<num;++i){ if(stp+n-st[stp][i]-1<=mans) break; if(stp+dp[st[stp][i]]<=mans) break; int tmp=0; for(int j=i+1;j<num;++j){ if(mpp[st[stp][i]][st[stp][j]]){ st[stp+1][tmp++]=st[stp][j]; } } dfs(stp+1,tmp); } } void solve(){ int cnt=0; for(int i=m-1;i>=0;--i){ cnt=0; for(int j=i+1;j<m;++j){ if(mpp[i][j]){ st[1][cnt++]=j; } } dfs(1,cnt);

杜教筛

拈花ヽ惹草 提交于 2020-03-01 08:21:55
杜教筛 前置技能树:积性函数 就是对于函数 \(f(x)\) 对于任意两个互质整数 \(a,b\) ,如果有 \(f(a)·f(b)=f(ab)\) 则 \(f\) 为积性函数 如果对任意 \(a,b\) 成立, \(f\) 为完全积性函数。 前置技能树:狄利克雷卷积 狄利克雷卷积是一种运算定义。 \(f*g=\sum\limits_{d|n}f(d)g(\frac nd)\) 其显然满足交换律。 前言 一般我们求积性函数有优秀的 \(O(n)\) 欧拉筛 但是实际运用中,我们往往需要得出积性函数的前缀和来进行运算,而且总是有一些毒瘤出题人把数据出到 \(1e10\) 之类,此时线性筛就不够用了。 为了解决这个问题,我们就需要一种新的筛法—杜教筛。 杜教筛是一种筛法,能够以 \(O(n^{\frac23})\) 的时间复杂度求积性函数的前缀和 此外好像还有 \(min\_25\) 筛,复杂度为 \(O(n^{\frac{3/4}{log_n}})\) 但是学不动了 \(Orz\) 具体推导 这个东西都是套路。。。 如果不想看公式了其实翻到下面加粗加大地方背个板子也挺不错 设 \(f(n)\) 为你要筛的函数, \(S(n)=\sum\limits_{i=1}^{n}f(i)\) 。 我们构造两个积性函数 \(h,g\) ,使得 \(h=g*f\) 。 \(\sum\limits_

从数据流中获取中位数

天大地大妈咪最大 提交于 2020-02-29 14:03:50
从数据流中获取中位数 需求描述 需求分析 C++代码如下 python代码 需求描述   有一个动态的数据流,如何比较快的获得数据流的中位数。这个过程中,数据流可能会有新的数据加入。中位数定义为元素个数为奇数的序列的排序结果中间位置元素值,偶数数列的排序结果中间位置的两个元素的元素值的平均。 需求分析   首先要获得数据流的中位数,这个问题可以轻易转换成 查找序列中的第k大的数 ,如果序列长度为偶数,则要查找两次,但是不会影响复杂度。但是现在还要处理的一个问题是,这个数据流的元素个数会增加的,元素一旦增加,很可能中位数就变了,如果再要获得就不会很方便。我们采用这个办法的话,就得重新查找中位数。   总结来看,我们查找一次中位数的时间复杂度是 O ( n ) O(n) O ( n ) ,分析在链接中的文章写得很清楚了。维护这样的数据流,每新来一个数据插入数据的时间复杂度就是 O ( 1 ) O(1) O ( 1 ) 了。因为要使用partition函数,所以这个数据流需要是顺序表的结构。   可能要多次查找中位数,我们维持一个排序的序列,要查找中位数只需要 O ( 1 ) O(1) O ( 1 ) 的时间复杂度。因为如果是顺序表的话,直接随机存储访问中间元素即可,如果是链表,我们需要设置两个指针,来指向中间元素,插入元素后这两个指针最多向后移动一个元素,不带来额外的复杂度

大数据处理面试题

假装没事ソ 提交于 2020-02-29 01:57:58
1. 给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url? 方an1:可以估计每个文件安的大小为50G×64=320G,远远大于内存限制的4G。所以不可能将其完全加载到内存中处理。kao虑采取分而治之的方法。 s 遍历文件a,对每个url求取 ,然后根据所取得的值将url分别存储到1000个小文件(记为 )中。这样每个小文件的大约为300M。 s 遍历文件b,采取和a相同的方式将url分别存储到1000各小文件(记为 )。这样处理后,所有可能相同的url都在对应的小文件( )中,不对应的小文件不可能有相同的url。然后我们只要求出1000对小文件中相同的url即可。 s 求每对小文件中相同的url时,可以把其中一个小文件的url存储到hash_set中。然后遍历另一个小文件的每个url,看其是否在刚才构建的hash_set中,如果是,那么就是共同的url,存到文件里面就可以了。 方an2:如果允许有一定的错误率,可以使用Bloom filter,4G内存大概可以表示340亿bit。将其中一个文件中的url使用Bloom filter映射为这340亿bit,然后挨个读取另外一个文件的url,检查是否与Bloom filter,如果是,那么该url应该是共同的url(注意会有一定的错误率)。 2. 有10个文件,每个文件1G

架构设计流程

无人久伴 提交于 2020-02-28 06:57:52
今天我们来总结一下架构设计流程,谈到架构设计我们先了解一下架构设计的原则 架构设计原则 架构设计主要可以归纳为三大原则 合适原则 简单原则 演化原则 合适原则 没那么多人,却想干那么多活,是失败的第一个主要原因 没有那么多积累,却想一步登天,是失败的第二个主要原因 没有那么卓越的业务场景,却幻想灵光一闪成为天才,是失败的第三个主要原因 简单原则 “复杂”在制造领域代表先进,在建筑领域代表领先,但在软件领域,却恰恰相反,代表的是“问题”。 软件领域的复杂性体现在以下两个方面 结构的复杂性 结构复杂的系统几乎毫无例外地具备两个特点 : 组成复杂系统的组件数量更多,同时这些 组件之间的关系也更加复杂 结构上的复杂性存在的第一个问题是 : 组件越多,就越有可能其中某个组件出现故障,从 而导致系统故障 结构上的复杂性存在的第二个问题是:某个组件改动,会影响关联的所有组件,这些被影 响的组件同样会继续递归影响更多的组件 结构上的复杂性存在的第三个问题是 : 定位一个复杂系统中的问题总是比简单系统更加困 难。首先是组件多,每个组件都有嫌疑,因此要逐一排查:其次组件间的关系复杂,有可能表 现故障的组件并不是真正问题的根源 逻辑复杂性 看到结构复杂性后,我们的第一反应可能就是“降低组件数量”,毕竟组件数量越少,系统 结构越简单。最简单的结构当然就是整个系统只有一个组件,即系统本身,所有的功能和逻辑

UCF Local Programming Contest 2015 H. Reach for the Stars

≯℡__Kan透↙ 提交于 2020-02-27 04:06:45
一看就是搜索或者状压。 但状压不好搞。 我们考虑搜索。 由于涂一个点,会涂十字 直接枚举所有点是否涂(做为中心点)的复杂度是2^81 但其实一个点为中心是否涂 只用判断7*7个,即复杂度压缩到2^49(只能在边界内涂,中心点不能是边界) 仔细观察发现,边界的点只能由次一层边界为中心点涂得。 即:x==2,y==2,x==r-1,y==c-1这些行列需要涂就必须涂,否则就不涂。 这样复杂度缩小为 2^25。是可以接受的复杂度了 然后就是降常数。 即加上最优性剪枝,可行性剪枝,就能过了。 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define ls (o<<1) #define rs (o<<1|1) #define pb push_back //#define a(i,j) a[(i)*(m+2)+(j)] //m是矩阵的列数 /* int head[M],cnt; void init(){cnt=0,memset(head,0,sizeof(head));} struct EDGE{int to,nxt,val;}ee[M*2]; void add(int x,int y,int z){ee[++cnt].nxt=head[x],ee[cnt].to=y,ee[cnt].val=z

过犹不及

半腔热情 提交于 2020-02-27 01:21:26
刚读了一段话,心里颇有感触,摘抄在此。 (摘抄)我曾经遇到过这样一个客户,他们坚信可配置的重要性,致使他们的应用有大概10000个可配置变量。新增代码变的异常艰难,因为要花大量的时间来维护配置应用程序和数据库。但是他们坚信需要这种程度的灵活性,因为每个客户都有不同的需求,需要不同的设置。可实际上他们只有19个客户,而且预计将来也不会超过50个,他们并没有很好的去权衡。 我们的产品平台又有多少过犹不及呢,需要这么灵活和复杂的配置吗?有多少功能几乎不会用到,又有多少为了灵活增加了代码的复杂度,增加了配置的复杂度,而这种灵活我们自从开发完毕就没有使用过,因为我们的客户更少,最重要的是,很多灵活的配置并没有发挥出他的优点,反而成了我们的鸡肋。一定要好好权衡利弊,并不是所有地方都需要灵活! 来源: oschina 链接: https://my.oschina.net/u/3389027/blog/3170720

动态数组

守給你的承諾、 提交于 2020-02-26 12:55:06
知识点 实现属于自己的动态数组类 分析时间复杂度: 增: O(n) 删: O(n) 改: 已知索引O(1);未知索引O(n) 查: 已知索引O(1);未知索引O(n) 主要操作 一些变量定义: data: 数组 size:当前数组中的元素个数 添加操作 描述: 在指定索引 index 位置添加元素。 思路: 先检查索引是否越界,没有越界的情况下继续往下执行,否则抛异常。 当 size >= data.length 时,进行扩容操作,大小扩容为(data.length * 2)。 当前面两步都没问题的情况下,进行添加操作,先将 index 位置后的元素整体向后移动,移动完毕后再将要添加的元素添加到 index 位置。 最后 size 不要忘记加 1。 public void add(int index, E e) { if (index < 0 || index > size) { throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size."); } // 数组容量不够的话就进行扩容 if (size >= data.length) { resize(2 * data.length); } for (int i = size - 1; i >= index; i--) {

求取一对符合要求的数(前后夹击,直至相遇)

感情迁移 提交于 2020-02-24 04:09:02
07: 和为给定数 描述: 给出若干个整数,询问其中是否有一对数的和等于给定的数。 输入: 共三行: 第一行是整数n(0 < n <= 100,000),表示有n个整数。 第二行是n个整数。整数的范围是在0到10^8之间。 第三行是一个整数m(0 <= m <= 2^30),表示需要得到的和。 输出: 若存在和为m的数对,输出两个整数,小的在前,大的在后,中间用单个空格隔开。若有多个数对满足条件,选择数对中较小的数更小的。若找不到符合要求的数对,输出一行No。 样例输入: 4 2 5 1 4 6 样例输出: 1 5 解法1:(二分查找) 将数组排序,复杂度是O(n×log(n)) 查找的时候,设置两个变量i和j,i初值是0,j初值是n-1.看a[i]+a[j],如果大于m,就让j 减1,如果小于m,就让i加1,直至a[i]+a[j]=m。 这种解法总的复杂度是O(n×log(n))的。 解法2: (相对更快) 将数组排序,复杂度是O(n×log(n)) 查找的时候,设置两个变量i和j,i初值是0,j初值是n-1.看a[i]+a[j],如果大于m,就让j 减1,如果小于m,就让i加1,直至a[i]+a[j]=m。 这种解法总的复杂度是O(n×log(n))的。 代码如下: # include <iostream> # include <cstdio> # include