- 博客(100)
- 收藏
- 关注
原创 树上最长路
树上存在最远的两个点(b,e),那么距离其他点x最远的点一定是b或者e。 因此可以任选一个点做dfs找到最远的点b,再从b做一次dfs找到e,最远距离便算出来了。 如果要求任意点x的最远距离,那么maxdis=max( dis(x,b) , dis(x,e) ); 定义d(i)表示点i到根结点的最远距离,那么把b和e分别做根结点进行dfsComputer 题意就是要求任意点的最远距离#inc
2016-05-12 18:39:29
798
原创 G. FQ 的函数
华中师范大学 2016 年“计蒜客杯”第十四届程序设计竞赛 G. FQ 的函数 Description FQ 是个喜欢数学的孩子。有一天,FQ 发明了一个函数 FQ(n,p)。FQ(n,p)的值描述了 n!最多可以被 p 的多少次幂整除,其中 p 为一个素数。 举例来说,对于 FQ(8,3),我们要考查 8! = 8×7×6×5×4×3×2×1 = 40320。
2016-05-10 13:08:42
1048
原创 D.最强单身狗
华中师范大学 2016 年“计蒜客杯”第十四届程序设计竞赛 D. 最强单身狗 Description 有若干只单身狗排成一排,编号从 l 到 r。GBX 发现,一个单身狗的编号的 二进制中 1 的数量越多,表示该单身狗越强(就是单身越久咯 -_-|||)。GBX 想 找到一只最强的单身狗和他做朋友(强者惺惺相惜吧 >_<)。 Input 输入一个 T(T ≤ 1000)表示 T 组数据
2016-05-10 12:43:41
1630
原创 树的重心
对于一个有n个结点的无根树,找一个点作为根,使得最大子树的结点数最小,换句话说,删除这个点后最大连通块的结点数最小。 任选一个点作为根,设d(i)表示以i为根的子树的结点个数,那么: 只需要一次dfs,连记忆化都不需要,因为没有重复计算。现在重点来了: 删除结点i之后,最大连通块有多少个结点呢? 结点i的子树中最大的有max{d(j)}个结点,i的“上方子树”中有n-d(i)个结点!po
2016-05-06 15:24:44
729
原创 树的最大独立集
任选一个结点当根,用d(i)表示以i为根结点的子树的最大独立集大小,结点i只有两种决策:选或不选。如果选了i,则i的儿子都不能选;如果不选i,那么问题转化成求i的所有儿子的d值再相加。状态转移方程: 其中s(i)和gs(i)分别是i的儿子集合与孙子集合。 实现方法:当计算出一个d(i)后,用它去更新i的父结点和祖父结点,所以每次只要记录父结点即可 poj2342 Anniversary p
2016-05-06 15:08:01
1012
原创 求解a^b % m
a^b % m==a^(b % phi(m) + phi(m) )%m ,证明见此处 如果m是质数(那么phi(m)=m-1)且b非常大,求b的过程中就需要取模,那么这个公式就有了意义
2016-04-23 11:20:32
621
原创 :-1: error: cannot open C:\Users\<username>\AppData\Local\Temp\main.obj.5136.0.jom for write
C:\Users***\AppData\Local\Temp这个目录是系统的临时文件目录。 原因是在创建Hello World项目时哪里的设置有问题,去 工具->选项->构建和运行,“使用jom代替nmake”前面的√取消
2016-03-17 17:07:27
11565
8
原创 快速排序(分治法O(nlogn))
划分问题:把数组的各个元素重排后分成左右两部分,使得左边的任意元素都小于等于右边的任意元素。 递归求解:把左右两部分分别排序。 合并问题:不用合并,因为此时数组已经完全有序。void qsort(int L,int R){ if(L>=R)return; int l=L,r=R; int key=a[l];//取a[l]为关键字 while(l<r){
2016-03-15 19:35:42
839
原创 最大连续和(分治法)O(nlogn)
分解:将序列分解成元素个数尽量相等的子序列,求出每个子序列的最大连续和 合并:合并子问题得到原问题的解,由于最大连续和的子序列要么完全在中点左边,要么完全在中点右边,要么就是横跨左右两边,所以比较这几种情况就可得出当前序列的最大连续和int maxsum(int l,int r){ if(l==r)return a[l]; int m=(l+r)/2; int Max=ma
2016-03-14 19:38:36
2420
原创 UVa208 消防车 (dfs+并查集)
UVa208 Firetruck 题意:一个n(n<=20)个结点的无向图,要求打印从结点1到结点k的所有路径。 解法:简单的dfs,但是会超时,因为有些结点不能到达k,所以搜索这些结点完全是多余的,可以用并查集将能到达k的结点放入一个集合,搜索这些结点就可以了。#include<cstdio>#include<cstring>#include<iostream>using namespa
2016-03-14 16:40:59
936
原创 中国剩余定理
int china(){ int M=1; for(int i=1;i<=n;i++){ M*=m[i]; } int ans=0; for(int i=1;i<=n;i++){ extend(M/m[i],m[i]);//扩展欧几里得算法求逆元 ans=(ans+a[i]*M/m[i]*x)%M; }
2016-03-04 09:26:58
306
原创 乘法逆元
满足x与y的乘积对z取模等于1时,x和y对于模数z来说互为逆元 即 x*y=1(mod z) 为什么要求逆元呢? 比如求 (b/a)mod p 时,如果b大到不可直接求出,我们可以先求出在模数p下与a互为逆元的数x,那么 (b/a)mod p 转化成 (b*x)mod p证明略。。。求逆元: 方法一(a和p互质,扩展欧几里算法): :a * x + p * y = gcd( a , p )
2016-03-02 22:19:47
1258
原创 扩展欧几里得算法
int x,y;void extend(int a,int b){ if(b==0){ x=1; y=0; return; } extend(b,a%b); int t=x; x=y; y=t-a/b*y;}
2016-03-02 21:55:28
362
原创 快速幂
采用二分的方法,复杂度O(logn) 取模的话可以直接加在函数里int fast(int a,int x){//计算a的x次方 if(x==0)return 1; if(x%2)return a*fast(a,x-1); int tmp=fast(a,x/2); return tmp*tmp;}如果计算 (a^x)%c ,其中a,x,c数据最大为 2^64-1 的
2016-03-01 22:17:19
395
原创 斐波拉契快速求法:矩阵快速幂
斐波拉契数:f0=0,f1=1,……..fn=f[n-1]+f[n-2] 用矩阵表示: 2*2的矩阵用结构体表示:struct node{ int a,b; int c,d;};2*2矩阵乘法:node mult(node x,node y){ return {x.a*y.a+x.b*y.c,x.a*y.b+x.b*y.d,x.c*y.a+x.d*y.c,x.c*y.b
2016-03-01 22:07:03
500
原创 树状数组
void init(){//初始化树状数组c for(int i=1;i<=n;i++){ for(int j=i-(i&-i)+1;j<=i;j++){ c[i]+=a[j]; } }}int query(int k){//前k项和 int sum=0; while(k){ sum+=c[k
2016-03-01 18:52:33
224
原创 最长公共子序列(LCS)
#include<cstdio>#include<cstring>#include<iostream>#include<stack>using namespace std;char a[1000+5],b[1000+5];int sum[1000+5][1000+5];void work(){ memset(sum,0,sizeof(sum)); int la=strlen
2016-02-28 19:36:17
364
原创 逆序数 归并排序求法
在将两个相邻的区间合并的时候统计逆序数当交换两个数的时候不会改变除了这两个数之外的数的逆序数,同理合并两个区间时不会改变除这两个区间外的数的逆序数。比如两个相邻的有序序列区间s1={3, 5, 6},s2={1, 4, 7}, 当第一个序列某个元素a[i]小于等于第二个序列的a[j]时逆序数为0,当a[i]>a[j]时,s1中a[i]后面的所有元素均大于等于a[i],也就大于a[j],所以逆序数就
2016-02-28 16:02:09
876
原创 归并排序
归并排序采用分治思想 使用了拆分及合并将两个有序的序列合并算法如下void merge(){ int i=1,j=1,k=1; while(i<=n&&j<=m){ if(a[i]<=b[j])c[k++]=a[i++]; else c[k++]=b[j++]; } while(i<=n)c[k++]=a[i++]; whil
2016-02-28 15:19:33
412
原创 用注册表修改软件默认安装路径
1.打开注册表编辑器 2.依次展开HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion 3.在右边双击ProgramFilesDir,将C:\Program FilesG(系统默认目录)修改成G:\Program Files(你想改的目录)64位系统还需要修改一个地方HKEY_LOCAL_MACHINE\SOFTWARE\Wow
2016-02-02 18:00:07
3478
原创 欧拉函数
#define N 100001int e[N];void Init(){ for(int i=1;i<=N;i++)e[i]=i; for(int i=2;i<=N;i+=2)e[i]/=2; for(int i=3;i<=N;i+=2) if(e[i]==i){ for(int j=i;j<=N;j+=i)
2015-12-28 19:06:54
321
原创 stringstream
头文件#include<sstream>常用于数据转换和分割字符串int n;string s="10 100 22";stringstream ss;//或者stringstream ss(s);ss<<s;while(ss>>n)//分割并且转换成数 cout<<n<<ends;cout<<endl;ss.clear();//sstream自带缓冲,所以要及时清除缓冲区s="
2015-12-28 18:29:28
382
原创 优先队列
头文件:#include<queue>1.整数越大优先级越高priority_queue<int>pq;2.整数越小优先级越高priority_queue<int,vector<int>,greater<int> >pq;3.结构体自定义优先级 原理:优先队列标准库中默认使用 “<” 操作符定义元素之间的优先级,所以自定义优先级时要重载了 “<” 操作符。struct node{ int
2015-12-28 10:22:36
338
原创 二维矩阵的一维访问方式
HDU1045Fire Net题意:点代表空地,X代表墙。问空地最多能放置多少个炮(炮能够向上下左右四个方向打,但是墙打不穿),使互相攻击不到?简单dfs,递归深度就是炮的个数,不过二维矩阵的访问方式要变成一维的,从1到n*n的方式访问,可以避免大量重复#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>usi
2015-12-09 13:55:09
668
原创 HDU5572平面几何问题
HDU 5572An Easy Physics Problem题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 给定圆柱体圆心坐标,半径 小球起点坐标,起始运动方向(向量) 终点坐标 问能否到达终点,小球运动中如果碰到圆柱体会反射(基本物理知识)思路: 根据高中平面几何知识很快找到判断方法,但是向量的代码实现有一些麻烦,浪费时间,使用平面几何向量模板会方便许多#include<cst
2015-12-04 22:39:21
984
原创 向量模板
#include<cmath>struct node{ double dis(node);//两点距离 //向量操作 node add(node);//加 double mul(node);//乘 node mul(double);//倍 double abs();//模长 node unt();//单位化 node neg();//取
2015-12-04 22:24:36
1109
原创 最长非降子序列O(nlogn)
在最长上升序列O(nlogn)中当计算出的两个状态a和b满足A[a] < A[b]且d[a] = d[b]时,取a是最优的,但在非降这个要求中我们要保留的是b,因为一样的元素取的是最后一个,比如{1,2,2}中会取到第二个2,所以g[i]表示d值为i的最最大状态编号(如果存在),因此将lower_bound(返回第一个等于value的值的位置)更换成upper_bound(返回最后一个等于value
2015-11-01 20:34:29
921
原创 最长上升子序列O(nlogn)
假设已经计算出的两个状态a和b满足A[a] < A[b]且d[a] = d[b],则对于后续所有的状态i(即i > a且i > b)来说,a并不会比b差——如果b满足A[b] < A[i]的条件,a肯定也满足,且二者的d值相同;但反过来却不一定了,a满足A[a] < A[i]的条件时,b却不一定满足。换句话说,如果我们只保留a,一定不会丢失最优解。 这样,对于相同的d值,只需保留A最小的一个。设g
2015-11-01 20:11:46
409
原创 最长上升子序列O(n^2)
从序列 {A[1] , A[2] , A[3] …… A[n] } 中选出尽量多的数(不改变先后顺序)组成一个上升序列(严格递增序列) 如{1,6,2,3,7,5},可以选出上升子序列{1,2,3,5},也可以选出{1,6,7},但前者更长。这是动态规划的问题,设d[i]为以i结尾的最长上升序列的长度,则状态转移方程:d[ i ] = max{ 0 , d[ j ] | j#include<ios
2015-11-01 19:44:28
365
原创 HDU2199二分法求根
HDU2199Can you solve this equation? y=8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6单调递增,所以直接二分法#include<cstdio>#include<cmath>#include<cstring>#include<iostream>#include<algorithm>using namespace std;double y;
2015-10-31 18:15:35
475
原创 Java大数类用法
在JAVA中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,至于两个类的对象能表示最大范围不清楚,理论上能够表示无线大的数,只要计算机内存足够大。 这两个类都在java.math.*包中,因此每次必须在开头处引用该包。Ⅰ基本函数: 1.valueOf(parament); 将参数转换为制定的类型 比如 int a=3; BigInteger b=Big
2015-10-31 17:21:03
13454
原创 HDU4135 容斥原理+质因子+DFS
HDU4135Co-prime 题意:求区间[A , B]内与N互质的数的个数分析: 将问题转换一下,用[1 , B]内与N互质的数的个数减去[1 , A-1]内与N互质的数的个数,现在就变成要求[1 , C]内与N互质的数的个数,这样不好求,但是求与N互质的数的个数(设为num)很简单,那么最后答案就是C-num 如何求与N不互质的数的个数: 比如C=12,N=30 第一步:求出N的所有
2015-10-27 18:31:09
484
原创 一次求多个整数的质因数
原理同素数筛法 的方法一,可以一次求[1,N]内所有整数的质因子(N不能太大,10^5左右)#include<iostream>#include<cstring>#include<vector>using namespace std;#define N 100000int vis[N+10];vector<int>a[N+10];void Init(){ for(int i=0;
2015-10-27 17:39:56
394
原创 求一个整数的质因数
适用于N的个数不是很多但是N又特别大(10^9)的情况,速度很快#include<iostream>using namespace std;int cnt;int a[1000];void Factor(int N){ cnt=0; for(int i=2;i*i<=N;i++){ if(N%i==0)a[++cnt]=i; while(N%i=
2015-10-27 16:19:49
613
原创 输出组合排列的方案
组合排列数值公式 要求输出具体方案用dfs实现非常简单,这里只针对不同元素#include<iostream>#include<algorithm>using namespace std;int a[100];int n,m;int path[100];void dfs(int cur,int len){ if(len==m){ for(int i=0;i<len;
2015-09-17 15:50:25
424
原创 输出全排列的方案
全排列数值有公式 非常简单 但是要求输出具体方案怎么办呢? 用dfs实现很简单,这里只针对不同元素的全排列,有相同的再另外考虑吧#include<iostream>#include<algorithm>using namespace std;int a[100],visited[100]={0};int n,m;int path[100];void dfs(int cur,int len
2015-09-17 15:49:56
415
原创 HDU1518 Square
HDU1518 Square 一般的DFS是搜索到一条满足就行了,这种题目是搜索多条满足题意:用上所有的长度组合成四条相等的边长#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int a[30],visited[30];int n,W;int flag;void dfs(int cur,i
2015-09-17 15:48:55
425
原创 HDU1157 连连看
HDU1157 连连看DFS 测试样例: 样例1: 3 2 0 1 0 2 0 1 1 1 2 3 2 YES样例2: 1 3 2 2 2 1 1 1 3 3 NO主要是解决初始方向问题就OK了#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;struct V{ in
2015-09-17 15:48:19
344
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅