2012.7.25 模版
来源:互联网 发布:java = 编辑:程序博客网 时间:2024/06/06 08:33
char -128 ~ +127 (1 Byte)
short -32767 ~ + 32768 (2 Bytes)
unsigned short 0 ~ 65536 (2 Bytes)
int -2147483648 ~ +2147483647 (4 Bytes)
unsigned int 0 ~ 4294967295 (4 Bytes)
long == int
long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes)
double 1.7 * 10^308 (8 Bytes)
unsigned int 0~4294967295
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
unsigned long long的最大值:1844674407370955161
__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615
卡特兰数:
1 通项公式:h(n)=C(n,2n)/(n+1)=(2n)!/((n!)*(n+1)!)
2递推公式:h(n)=((4*n-2)/(n+1))*h(n-1); h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)*h(0).
3前几项为:h(0)=1,h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,......
#include<iostream>
using namespace std;
int a[101][101]={0};
int main()
{
int n,i,j,len,r,temp,t;
int b[101];
a[1][0] = 1;
len = 1;
b[1] = 1;
for(i=2;i<=100;i++)
{
t = i-1;
for(j=0;j<len;j++) //乘法
a[i][j] = a[i-1][j]*(4*t+2);
for(r=j=0;j<len;j++) //处理相乘结果
{
temp = a[i][j] + r;
a[i][j] = temp % 10;
r = temp / 10;
}
while(r) //进位处理
{
a[i][len++] = r % 10;
r /= 10;
}
for(j=len-1,r=0;j>=0;j--) //除法
{
temp = r*10 + a[i][j];
a[i][j] = temp/(t+2);
r = temp%(t+2);
}
while(!a[i][len-1]) //高位零处理
len --;
b[i] = len;
}
while(cin>>n)
{
for(j=b[n]-1;j>=0;j--)
printf("%d",a[n][j]);
printf("\n");
}
return 0;
}
KMP算法
int get_nextval(SString T,int &nextval[ ]){
i=1; nextval[1]=0; j=0;
while(i<T[0]){
if(j==0||T[i]==T[j]){
++i;++j;
if (T[i]!=T[j]) nextval[i]=j;
else nextval[i]=nextval[j];
}
else j=nextval[j];
}
}
欧拉函数
C语言:
int eular(int n)
{
int ret=1,i;
for(i=2;i*i<=n;i++)
if(n%i==0)
{
n/=i,ret*=i-1;
while(n%i==0)
n/=i,ret*=i;
}
if(n>1)
ret*=n-1;
return ret;
}
#include <stdlib.h>
#define N 10000000
main()
{
int *phi,i,j;
char *prime;
prime=(char*)malloc((N+1)*sizeof(char));
prime[0]=prime[1]=0;
for(i=2;i<=N;i++)
{
prime[i]=1;
}
for(i=2;i*i<=N;i++)
{
if(prime[i])
{
for(j=i*i;j<=N;j+=i)
{
prime[j]=0;
}
}
} //这段求出了N内的所有素数
phi=(int*)malloc((N+1)*sizeof(int));
for(i=1;i<=N;i++)
{
phi[i]=i;
}
for(i=2;i<=N;i++)
{
if(prime[i])
{
for(j=i;j<=N;j+=i)
{
phi[j]=phi[j]/i*(i-1); //此处注意先/i再*(i-1),否则范围较大时会溢出
}
}
欧几里德算法的C++语言描述
int Gcd(int a, int b)
{
if(b == 0)
return a;
return Gcd(b, a % b);
}
扩展欧几里德定理
int exGcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int r = exGcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return r;
}
p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),p * a+q * b = c的其他整数解满足:
p = p1 + b/Gcd(a, b) * t
q = q1 - a/Gcd(a, b) * t(其中t为任意整数)
p 、q就是p * a+q * b = c的所有整数解。
约瑟夫环
#include <stdio.h>
int main(void)
{
int n, m, i, s=0;
printf ("N M = ");
scanf("%d%d", &n, &m);
for (i=2; i<=n; i++)
s=(s+m)%i;
printf ("The winner is %d\n", s);
return 0 ;
}
汉诺塔
#include<stdio.h>
int k,n;
void hanoi(int n,char x,char y,char z)
{
if(n==1) k++,printf("%c->%c\n",x,z);
else
{
hanoi(n-1,x,z,y);
k++,printf("%c->%c\n",x,z);
hanoi(n-1,y,x,z);
}
}
int main()
{
while(~scanf("%d",&n))
{
k=0,hanoi(n,'1','2','3');
printf("sumstep=%d\n",k);
}
}
二分算法
while (low < high) //返回刚好比a大的位置
{
mid = (low + high)/2;
if (a < b[mid])
high = mid ;
else if (a > b[mid])
low = mid + 1;
else if(a == b[mid])
break;
}
return low;
斐波拉契数列
F(n)=(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}
F(n) = [ (( sqrt ( 5 ) + 1 ) / 2) ^ n ]其中[ x ]表示取距离 x 最近的整数。
从第二项开始,每个奇数项的平方都比前后两项之积多1,每个偶数项的平方都比前后两项之积少1。
{f(n), f(n-1), f(n-1), f(n-2)} ={1, 1, 1,0}n-1
f(m+n-1)=f(m-1)·f(n-1)+f(m)·f(n)。
Fib[n+2]-1 = Fib[1]+Fib[2]+...Fib[n]
A^B%C、
unsigned mod(unsigned x, unsigned y,unsigned n)
{
unsigned s=1;
while(y)
{
if(y&1) // a^b=(a*a)^(b/2)*a^(y&1)
s=(s*x)%n;
y>>=1;
x=(x*x)%n;
}
return s;
}
Coj 1053斐波拉契数列+矩阵连乘
#include<stdio.h>
const int N=2;
long long a,b,p;
long long fib(long long n)
{
long long f[2][2]={{1,1},{1,0}},g[2][2]={{1,0},{0,1}},h[2][2];
int i,j,k;
while(n>0)
{
if(n&1)
{
for(i=0;i<N;i++)
for(j=0;j<N;j++)
for(h[i][j]=k=0;k<N;k++)
h[i][j]+=f[i][k]*g[k][j];
for(i=0;i<N;i++)
for(j=0;j<N;j++)
g[i][j]=h[i][j]%p;
}
for(i=0;i<N;i++)
for(j=0;j<N;j++)
for(h[i][j]=k=0;k<N;k++)
h[i][j]+=f[i][k]*f[k][j];
for(i=0;i<N;i++)
for(j=0;j<N;j++)
f[i][j]=h[i][j]%p;
n>>=1;
}
return g[0][1];
}
int main()
{
int r;
while(scanf("%lld%lld%lld",&a,&b,&p)!=EOF)
{
a=fib(a+1);
b=fib(b+2);
b=(b-a+p)%p,r=p,a=1;
while(r)
{
if(r&1) a=(a*b)%p;
b=(b*b)%p;
r>>=1;
}
printf("%I64d\n",a);
}
}
正整数n的因子之和
n=p1e1p2e2…prer
Sum=(1+p1+p12+…+p1e1)*(1+p2+p22+…+p2e2) *…*(1+pr+pr2+…+prer)
gcd Stein算法
int gcd(int a, int b)
{
if(a==0)
return b;
if(b == 0) return a;
if(a%2==0&&b%2==0)
return 2*gcd(a>>1,b>>1);
else if(a%2==0)
return gcd(a>>1,b);
else if(b%2==0)
return gcd(a,b>>1);
else
return gcd(abs(a-b),Min(a,b));
}
DP
母函数模版
#include<iostream>
#include<stdio.h>
using namespace std;
const int maxn=121;
int main()
{
int c[maxn],d[maxn];
int i,j,k;
for(i=0;i<maxn;i++)
c[i]=1,d[i]=0;
for(i=2;i<maxn;i++)
{
for(j=0;j<maxn;j++)
{
for(k=0;k+j<maxn;k+=i)
{
d[j+k]+=c[j];
}
}
for(j=0;j<maxn;j++)
{
c[j]=d[j];
d[j]=0;
}
}
while(scanf("%d",&k)!=EOF)
{
printf("%d\n",c[k]);
}
return 0;
}
最长(非)上升子序列
1.二分+贪心
#include<stdio.h>
#include<iostream>
using namespace std;
const int MAX=1001;
int main()
{
int n,i,j,k1,k2,max1,max2;
int dp1[MAX],dp2[MAX],s[MAX];
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)
scanf("%d",s+i);
dp2[1]=dp1[1]=s[1],max1=max2=k1=k2=1;
for(i=2;i<=n;i++)
{
if(s[i]<=dp1[k1])
{
dp1[++k1]=s[i];
max1=k1>max1?k1:max1;
}
else
{
int low=1,high=k1,mid;
while(low<high)
{
mid=(low+high)/2;
if(dp1[mid]>s[i]-1) low=mid+1;
else if(dp1[mid]<s[i]) high=mid;
}
dp1[low]=s[i];
}
if(s[i]>dp2[k2])
{
dp2[++k2]=s[i];
max2=k2>max2?k2:max2;
}
else
{
int low=1,high=k2,mid;
while(low<high)
{
mid=(low+high)/2;
if(dp2[mid]>s[i]) high=mid;
else if(dp2[mid]<s[i]) low=mid+1;
else { low=mid; break; }
}
dp2[low]=s[i];
}
}
printf("%d %d\n",max1,max2);
}
}
O(n^2)
#include<stdio.h>
#include<iostream>
using namespace std;
const int MAX=30001;
int main()
{
int n,i,j,max1,max2;
int dp1[MAX],dp2[MAX],s[MAX];
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)
scanf("%d",s+i);
for(i=1;i<=n;i++)
dp2[i]=dp1[i]=1;
for(i=2;i<=n;i++)
{
for(j=1;j<i;j++)
{
if(s[j]>=s[i])
{
dp1[i]=dp1[j]+1>dp1[i]?dp1[j]+1:dp1[i];
}
else
{
dp2[i]=dp2[j]+1>dp2[i]?dp2[j]+1:dp2[i];
}
}
}
max1=max2=1;
for(i=2;i<=n;i++)
{
max1=dp1[i]>max1?dp1[i]:max1;
max2=dp2[i]>max2?dp2[i]:max2;
}
printf("%d %d\n",max1,max2);
}
}
最长公共子序列
#include<stdio.h>
#define max(a,b) a > b? a : b
const int MAX=5001;
int i, j, n;
short dp[MAX+1][MAX+1];
char str[MAX+1];
int main()
{
while( ~scanf("%d",&n) )
{
scanf( "%s" , str+1 );
for ( i = 0 ; i <= n ; i++ ) for ( j = 0 ; j <= n ; j++ ) dp[i][j] = 0;
for ( i = 1 ; i <= n ; i++ )
for ( j = n ; j > 0 ; j-- )
{
dp[i][n-j+1] = str[i] == str[j]? dp[i-1][n-j]+1 : max( dp[i-1][n-j+1] , dp[i][n-j] ) ;
}
printf("%d\n", n-dp[n][n] );
}
}
背包九讲
0 – 1背包
POJ 3624
#include<iostream>
#include<stdio.h>
using namespace std;
int n,m,i,j;
int w[3410],d[3410],f[12881];
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
scanf("%d %d",&w[i],&d[i]);
for(i=0;i<=m;i++)
f[i]=0;
for(i=1;i<=n;i++)
{
for(j=m;j-w[i]>=0;j--)
{
f[j]=f[j]>(f[j-w[i]]+d[i])?f[j]:(f[j-w[i]]+d[i]);
if(i==n) break;
}
}
printf("%d\n",f[m]);
}
return 0;
}
完全背包
hdu 1114
#include<iostream>
#include<stdio.h>
using namespace std;
#define INF 0x3fffffff
int main()
{
int cas,e,f,i,j,n,k;
int p[510],w[510],fu[10010];
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&e,&f);
f-=e;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d",&p[i],&w[i]);
fu[0]=0;
for(i=1;i<=f;i++)
fu[i]=INF;
for(i=1;i<=n;i++)
{
for(j=w[i];j<=f;j++)
{
fu[j]=fu[j]<fu[j-w[i]]+p[i]? fu[j]:fu[j-w[i]]+p[i];
}
}
if(fu[f]==INF) printf("This is impossible.\n");
else printf("The minimum amount of money in the piggy-bank is %d.\n",fu[f]);
}
}
多重背包
hdu 2191 二进制法
#include<stdio.h>
int main()
{
int n,m,cas,i,j,num,k;
int p[110],w[110],s[110],f[110];
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
scanf("%d%d%d",&p[i],&w[i],&s[i]);
for(i=0;i<=n;i++) f[i]=0;
for(i=0;i<m;i++)
{
k=1;
while(k<s[i])
{
num=p[i]*k;
for(j=n;j>=num;j--)
f[j]=f[j]>(f[j-num]+w[i]*k)?f[j]:f[j-num]+w[i]*k;
s[i]-=k;
k*=2;
}
num=p[i]*s[i];
for(j=n;j>=num;j--)
f[j]=f[j]>f[j-num]+w[i]*s[i]?f[j]:f[j-num]+w[i]*s[i];
}
printf("%d\n",f[n]);
}
}
单调队列 poj2823
#include "stdio.h"
#include "string.h"
const int M=1000005;
int arr[M];
int Minq[M],Maxq[M];
int Q[M],Inq[M];
int n,k;
void Min()
{
int head=1,tail=0;
int i;
for(i=1;i<=n;i++)
{
while(head<=tail && Q[tail]>arr[i])
tail--;
tail++;
Q[tail]=arr[i];
Inq[tail]=i;
if(i>=k)
{
while(Inq[head]<=i-k) head++;
Minq[i-k]=Q[head];
}
}
}
void Max()
{
int head=1,tail=0;
int i;
for(i=1;i<=n;i++)
{
while(head<=tail && Q[tail]<arr[i])
tail--;
tail++;
Q[tail]=arr[i],Inq[tail]=i;
if(i>=k)
{
while(Inq[head]<=i-k)
head++;
Maxq[i-k]=Q[head];
}
}
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
if(k>n) k=n;
int i;
for(i=1;i<=n;i++)
scanf("%d",&arr[i]);
Min();
Max();
for(i=0; i<n-k+1; i++)
printf("%d%c", Minq[i], (i < n - k) ? ' ' : '\n');
for(i=0; i<n-k+1; i++)
printf("%d%c", Maxq[i], (i < n - k) ? ' ' : '\n');
}
return 0;
}
单调队列多重背包hdu 2191
#include<stdio.h>
const int N=110;
int main()
{
int n,m,cas,i,j,k,y,head,tail;
int p[N],w[N],s[N],f[N],u[N],v[N];
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
scanf("%d%d%d",&p[i],&w[i],&s[i]);
for(i=0;i<=n;i++) f[i]=0;
for(i=0;i<m;i++)
{
for(j=0;j<p[i];j++)
{
head=0,tail=-1;
for(k=0;k<=(n-j)/p[i];k++)
{
y=f[j+k*p[i]]-k*w[i];
while(head<=tail&&u[tail]<=y) tail--;
//去掉队列中不可能为最大值大数据
u[++tail]=y,v[tail]=k;
while(head<=tail&&v[tail]-v[head]>s[i]) head++;
//保证队列首尾差值数量不大于当前物品的数量
f[j+k*p[i]]=u[head]+k*w[i];
}
}
}
printf("%d\n",f[n]);
}
}
二维背包hdu3496
#include<stdio.h>
int cas,n,m,time,i,j,k,t,v;
int f[1010][110];
int main()
{
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d%d",&n,&m,&time);
for(i=0;i<=time;i++)
for(j=0;j<=m;j++)
f[i][j]=-100000000;
f[0][0]=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&t,&v);
for(j=time;j>=t;j--)
for(k=m;k>0;k--)
f[j][k]=f[j-t][k-1]+v>f[j][k]?f[j-t][k-1]+v:f[j][k];
}
for(i=v=0;i<=time;i++) v=f[i][m]>v?f[i][m]:v;
printf("%d\n",v);
}
}
分组背包hdu1712
#include<stdio.h>
#include<iostream>
using namespace std;
int max(int a,int b)
{
if(a>b) return a;
return b;
}
int main()
{
int n,m,i,j,k,t,c;
int dp[110],w[110];
while(~scanf("%d%d",&n,&m),n||m)
{
for(i=0;i<=m;i++) dp[i]=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
scanf("%d",&w[j]);
for(k=m;k>=0;k--)
for(j=1;j<=m;j++)
{
if(k-j>=0) dp[k]=max(dp[k],dp[k-j]+w[j]);
}
}
printf("%d\n",dp[m]);
}
return 0;
}
分组背包 每组至少选择一个 状态转移方程 如下:
dp[i][t]=max(dp[i][t],dp[i][t-p[i][j]]+v[i][j]);
dp[i][t]=max(dp[i][t],dp[i-1][t-p[i][j]]+v[i][j]);
依赖背包
1.转化为分组背包方法 NOIP2006金明的预算方案
#include <iostream>
#include <cmath>
using namespace std;
struct node {
int v,p,q;
}data[61];
int n, m, _max;
int ans[32001],f[60][32001];
int main() {
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(f, -1, sizeof(f));
f[0][0] = 0;
n /= 10;
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d",&data[i].v,&data[i].p,&data[i].q);
data[i].v /= 10,data[i].p*=data[i].v;
f[i][0] = 0;
}
for(int i = 1; i <= m; i++)
{
if(data[i].q == 0) continue;
for(int j = n; j >= data[i].v; j--)
{
if(f[data[i].q][j - data[i].v] != -1)
f[data[i].q][j]=max(f[data[i].q][j],f[data[i].q][j-data[i].v]+data[i].p);
}
}
for(int i = 1; i <= m; i++)
{
if(data[i].q != 0) continue;
for(int j = n; j >= 0; j--)
{
if(f[i][j] != -1)
{
if(j + data[i].v <= n)
f[i][j + data[i].v] = max(f[i][j + data[i].v], f[i][j] + data[i].p);
f[i][j] = -1;
}
}
}
memset(ans, -1, sizeof(ans));
ans[0] = _max = 0;
for(int i = 1; i <= m; i++) {
if(data[i].q != 0) continue;
for(int j = n; j >= data[i].v; j--) {
for(int k = j; k >= data[i].v; k--) {
if(f[i][k] != -1 && ans[j - k] != -1) {
ans[j] = max(ans[j], f[i][k] + ans[j - k]);
}
}
}
}
for(int i=0;i<=n;i++)
_max = max(_max, ans[i]);
printf("%d\n",_max*10);
}
return 0;
}
2. 二附件依赖背包方法
#include<stdio.h>
const int MAX=32001;
const int M=61;
int main()
{
int n,m,i,j,k,y,max;
int p[M],q[M],v[M],a[5];
int dp[MAX];
while (~scanf("%d %d",&n,&m))
{
n/=10;
for (i=0;i<=n;i++) dp[i]=0;
for (i=1;i<=m;i++)
{
scanf("%d %d %d",&v[i],&p[i],&q[i]);
v[i]/=10,p[i]*=v[i];
}
for (i=1;i<=m;i++)
{
if (q[i]==0)
{
for (k=0,j=1;j<=m;j++)
{
if (q[j]==i)
{
a[++k]=j;
}
}
if (k==0)
{
for (y=n;y>=v[i];y--) dp[y]=dp[y-v[i]]+p[i]>dp[y]?dp[y-v[i]]+p[i]:dp[y];
}
else if (k==1)
{
for (y=n;y>=v[i];y--)
{
max=dp[y];
max=dp[y-v[i]]+p[i]>max? dp[y-v[i]]+p[i]:max;
if(y-v[i]-v[a[1]]>=0) max=dp[y-v[i]-v[a[1]]]+p[i]+p[a[1]]>max?dp[y-v[i]-v[a[1]]]+p[i]+p[a[1]]:max;
dp[y]=max;
}
}
else if(k==2)
{
for (y=n;y>=v[i];y--)
{
max=dp[y];
max=dp[y-v[i]]+p[i]>max?dp[y-v[i]]+p[i]:max;
if(y-v[i]-v[a[1]]>=0) max=dp[y-v[i]-v[a[1]]]+p[i]+p[a[1]]>max?dp[y-v[i]-v[a[1]]]+p[i]+p[a[1]]:max;
if(y-v[i]-v[a[2]]>=0) max=dp[y-v[i]-v[a[2]]]+p[i]+p[a[2]]>max?dp[y-v[i]-v[a[2]]]+p[i]+p[a[2]]:max;
if(y-v[i]-v[a[1]]-v[a[2]]>=0) max=dp[y-v[i]-v[a[1]]-v[a[2]]]+p[i]+p[a[1]]+p[a[2]]>max?dp[y-v[i]-v[a[1]]-v[a[2]]]+p[i]+p[a[1]]+p[a[2]]:max;
dp[y]=max;
}
}
}
}
printf("%d\n",10*dp[n]);
}
return 0;
}
Hdu3449
#include<stdio.h>
using namespace std;
int n,w,i,j,k,m,p,c,v;
int dp[100001],f[100001];
int main()
{
while(scanf("%d%d",&n,&w)!=EOF)
{
for(i=0;i<=w;i++) dp[i]=0;
for(i=1;i<=n;i++)
{
scanf("%d%d",&p,&m);
for(j=w;j>=p;j--) f[j]=dp[j-p]; //继承上一层的结果
while(j>=0) f[j--]=-1;
for(j=1;j<=m;j++)
{
scanf("%d%d",&c,&v);
for(k=w;k>=c;k--)
if(f[k-c]!=-1)
f[k]=f[k-c]+v>f[k]?f[k-c]+v:f[k];//01背包部分
}
for(j=w;j>=0;j--) //如果能更新上一层的状态,就更新。
dp[j]=f[j]>dp[j]?f[j]:dp[j];
}
printf("%d\n",dp[w]);
}
return 0;
}
米勒罗宾算法
POLLARD启发式搜索
计算几何
三角形内切圆半径:r=2*s/(a+b+c);
三角形外接圆半径为R=(a*b*c)/(s*4);
s是三角形面积 a,b,c是三角形三边。S=√[p(p-a)(p-b)(p-c)]=1/2*a*b*sinC
- 2012.7.25 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- 模版
- Dinic模版+SAP模版
- bign模版高精度模版
- 模版——函数模版、类模版
- 模版template
- 创建模版
- iOS 5 Storyboard 入门
- 解决MySQL数据库乱码问题
- 0717
- CPU玩的是效率!超线程双核PK物理三核
- HDU 3511扫描线
- 2012.7.25 模版
- Unity3D在移动端的优化处理
- CVE2012-1723 Java Field Bytecode Verifier Cache RCE分析
- Linux下用到数据库sqlite3
- Flex主题教程系列3--Flex生命周期之出生时期
- 实习日志5
- MFC获取本机IP
- 实习日志6
- Asp.Net+Jquery.Ajax详解2-$.Load