《上海交通大学ACM算法模板》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
ACM算法模板集Contents一.常用函数与STL二.重要公式与定理1.FibonacciNumber2.LucasNumber3.CatalanNumber4.StirlingNumber(SecondKind)5.BellNumber6.Stirling'sApproximation7.SumofReciprocalApproximation8.YoungTableau9.整数划分10.错排公式11.三角形内切圆半径公式12.三角形外接圆半径公式13.圆内接四边形面积公式14.基础数论公式三.大数模板,字符读入四.数论算法1.GreatestCommonDivisor最大公约数2.Prime素数判断3.SievePrime素数筛法4.ModuleInverse模逆元5.ExtendedEuclid扩展欧几里德算法6.ModularLinearEquation模线性方程(同余方程)7.ChineseRemainderTheorem中国余数定理(互素于非互素)8.EulerFunction欧拉函数9.Farey总数9.Farey序列构造10.Miller_Rabbin素数测试,Pollard_rho因式分解五.图论算法1.最小生成树(Kruscal算法)2.最小生成树(Prim算法)3.单源最短路径(Bellman-ford算法)
11.单源最短路径(Dijkstra算法)2.全源最短路径(Folyd算法)3.拓扑排序4.网络预流和最大流5.网络最小费用最大流6.网络最大流(高度标号预流推进)7.最大团8.二分图最大匹配(匈牙利算法)9.带权二分图最优匹配(KM算法)10.强连通分量(Kosaraju算法)11.强连通分量(Gabow算法)12.无向图割边割点和双连通分量13.最小树形图0(N人3)14.最小树形图O(VE)六.几何算法1.几何模板2.球面上两点最短距离3.三点求圆心坐标4.三角形几个重要的点七.专题讨论1.树状数组2.字典树3.后缀树4.线段树5.并查集6.二叉堆7.逆序数(归并排序)8.树状DP9.欧拉路10.八数码11.高斯消元法12.字符串匹配(KMP算法)13.全排列,全组合14.二维线段树15.稳定婚姻匹配16.后缀数组17.左偏树18.标准RMQ-ST19.度限制最小生成树20.最优比率生成树(0/1分数规戈I)
21.最小花费置换2.区间K大数3.LCA-RMQ-ST4.LCA-larjan5.指数型母函数6.指数型母函数(大数据)7.单词前缀树(字典树+KMP)8.FFT(大数乘法)9.二分图网络最大流最小割10.混合图欧拉回路11.无源汇上下界网络流12.二分图最小点权覆盖13.带约束的轨道计数(Burnside引理)14.三分法求函数波峰15.单词计数,矩阵乘法16.字符串和数值hash17.滚动队列,前向星表示法18.最小点基,最小权点基第一章常用函数和STL一.常用函数#include
3doubleexp(doublearg);〃求num的对数,基数为edoublelog(doublenum);〃求num的根
4doublesqrt(doublenum);〃求base的exp次方doublepow(doublebase,doubleexp);#include
5umzstr);//num=24;str=,'hellon;〃字符串比较,返回值vO代表strlvstr2,=0代表strl=str2,>0代表st「l>str2intstrcmp(constchar*strlzconstchar*str2);常用STL[标准container概要]vector
6erase()从字符串移除元素find()查找元素insert()插入元素length()字符串长度replace。替换元素substr()取子字符串swap()交换字符串第二章重要公式与定理1.FibonacciNumber0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610...Formula:F[0]=0;F[l]=1;F[i]=F[i-l]+F[i-2],^(i+11+75p.F[n]==-=l~^——12血V5V5|2jI2.LucasNumber1,3,4,7,11,18,29,47,76,123...Formula:L[n]=n1.CatalanNumber1,2,5,14,42,132,429,1430,4862,16796,58786,208012...Formula:C(2n,n)Cln]=—~—(n+1)n=3;Application:1)将n+2边形沿弦切割成n个三角形的不同切割数2)n+1个数相乘,给每两个元素加上括号的不同方法数Sample:
7n=2;(1(23)),((12)3)n=3;(1(2(34))),(1((23)4)),((12)(34)),((1(23))4),(((12)3)4)2)n个节点的不同形状的二叉树数(严《数据结构》P.155)4)从n*n方格的左上角移动到右下角不升路径数Sample:1.StirlingNumber(SecondKind)S(n,m)表示含n个元素的集合划分为m个集合的情况数或者是n个有标号的球放到m个无标号的盒子中,要求无一为空,其不同的方案数Formula:r0(m=0arn
8i)£=01.Stirling'sApproximation2.SumofReciprocalApproximationEulerGamma=0.57721566490153286060651209;(11>一=lii(n)+EikLexGanvna:(n-»co)8.YoungTableauYoungTableau(杨式图表)是一个矩阵,它满足条件:如果格子[i,j]没有元素,贝旺i+1,"也一定没有元素如果格子[i,j]有元素a[i,j],则[i+1,j]要么没有元素,要么a[i+l,j]>a[i,j]Y[n]代表n个数所组成的杨式图表的个数Formula:Y[l]=1;Y[2]=2;Y(n]=Y[n-1]+(n-1)*Y[n-2];(n>2)9.整数划分将整数n分成k份,且每份不能为空,任意两种分法不能相同1)不考虑顺序for(intp=l;p<=n;p++)for(inti=p;i<=n;i++)for(intj=k;j>=l;j-)dp[i][j]+=dp[i-p][j-l];cout< 9d[n]=(n-1)*(d[n-1]+d[n-2]);8.三角形内切圆半径公式2Sr=;a+b+cp=(a+b+c)/2;S=Vp(p-a)(p-b)(p-c);9.三角形外接圆半径公式abcR=k10.圆内接四边形面积公式a+b*c+dP=——2;S=V(p-a)(p-b)(p-c)(p-d);11.基础数论公式1)模取募an%b=((((a*b)*a)%b)...)%b;2)n的约数的个数n=*32^*33^*.・.*31nll若n满足,则n的约数的个数为(ill+1)(112+1)(113+1)...(inn+1);第三章大数模板typedefinthugeint;〃应不大于,以防乘法时溢出constintBase=1000;constintCapacity=1000;structxnum{intLen;intData[Capacity];xnum():Len(0){}xnum(constxnum&V):Len(V.Len){memcpy(Dataz\/.DatazLen*sizeof*Data);}xnum(intV):Len(O){for(;V>0;V/=Base)Data[Len++]=V%Base;}xnum(charS[]);xnum&operator=(constxnum&V){Len=V.Len;memcpy(DatazV.Data,Len*sizeof*Data);return*this;} 10int&operator[](intIndex){returnData[Index];}intoperator[](intIndex)const{returnData[Index];}voidprint(){printf("%d"zLen==O?O:Data[Len-l]);for(inti=Len-2;i>=0;i)for(intj=Base/10;j>0;j/=10)printf("%d"zData[i]/j%10);}};xnum::xnum(charS[]){intI,J;Data[Len=0]=0;J=1;for(I=strlen(S)-l;I>=0;I-){Data[Len]+=(S[I]-'0')*J;J*=10;if(J>=Base)J=1,Data[++Len]=0;}if(Data[Len]>0)Len++;}intcompare(constxnum&Azconstxnum&B){inti;if(A.Len!=B.Len)returnA.Len>B.Len?1:-1;for(I=A.Len-1;I>=0&&A[I]==B[I];I-);if(I<0)return0;returnA[I]>B[I]?1:-1;}xnumoperator+(constxnum&Azconstxnum&B){xnumR;intI;intCarry=0;for(I=0;I 11elseR[I+J]=Carry%Base;Carry/=Base;}}returnR;}xnumoperator/(constxnum&A,constintB){xnumR;intI;hugeintC=0;for(I=A.Len-1;I>=0;I-){C=C*Base+A[I];R[I]=C/B;C%=B;}R.Len=A.Len;while(R.Len>0&&R[R.Len-1]==0)R.Len—;returnR;}//divxnumoperator/(constxnum&A,constxnum&B){intI;xnumRzCarry=0;intLeft,Right,Mid;for(I=A.Len-1;I>=0;I-){Carry=Carry*Base+A[I];Left=0;Right=Base-1;while(Left 12classBigNum{private:inta[1000];〃可以控制人数的位数intlen;〃大数长度public:BigNum(){len=1;memset(az0zsizeof(a));}BigNum(constint);BigNum(constchar*);BigNum(constBigNum&);BigNum&operator=(constBigNum&);BigNumoperator+(constBigNum&)const;BigNumoperator-(constBigNum&)const;BigNumoperator*(constBigNum&)const;BigNumoperator/(constint&)const;BigNumoperator人(constint&)const;intoperator%(constint&)const;booloperator>(constBigNum&T)const;voidprint();};BigNum::BigNum(constintb){intc,d=b;len=0;memset(a,0,sizeof(a));while(d>MAXN){c=d-(d/(MAXN+1))*(MAXN+l);d=d/(MAXN+1);a[len++]=c;}a[len++]=d;}BigNum::BigNum(constchar*s){intt,k,index/,i;memset(azOzsizeof(a));l=strlen(s);len=l/DLEN;if(l%DLEN)len++;index=0;for(i=l-l;i>=0;i-=DLEN){t=O;k=i-DLEN+l;if(k 13while(tl.a[len-1]==0&&tl.len>1){tl.len—;big—;}if(flag)tl.a[big-l]=O-tl.a[big-l];returntl;}BigNumBigNum::operator*(constBigNum&T)const{BigNumret;inti,j,up;inttemp,templ;for(i=0;i 14constintok=1;intget_val(int&ret){ret=0;charch;while((ch=getchar())>'9'11ch<,0');do{ret=ret*10+ch-'O';}while((ch=getchar())<='9'&&ch>=*0');returnok;}〃带负数intget_val(int&ret){ret=0;charch;boolneg=false;while(((ch=getchar())>'9'11ch<,0')&&ch!='-');if(ch==*-*){neg=true;while((ch=getchar())>'9'11ch<'0');}do{ret=ret*10+ch-10';}while((ch=getchar())<='9*&&ch>=*0');ret=(neg?-ret:ret);returnok;}〃读取整数,可判EOF和EOLconstinteof=-l;constinteol=-2;intget_val(int&ret){ret=Ojcharch;while(((ch=getchar())>'9'||ch<*0,)&&ch!=EOF);if(ch==EOF)returneof;do{ret=ret*10+ch-'0,;}while((ch=getchar())<='9,&&ch>=*0,);if(ch==* 15')returneol;returnok;}〃读取浮点数intget_val(double&ret){ret=Ojdoublebase=O.ljcharch;booldot=false,neg=false;while(((ch=getchar())>'9'11ch<,0')&&ch!=&&ch!=;if(ch=={neg=true;while(((ch=getchar())>*9'11ch<,0')&&ch!=&&ch!=*-');}do{if(ch=={dot=true;continue;}if(dot){ret+=(ch-'O')*base;base*=0.1;}elseret=ret*10+(ch-'O1);}while(((ch=getchar())<=,9'&&ch>=*0')11ch==''');ret=(neg?-ret:ret);returnok;}第四章数论算法1.GreatestCommonDiviso「最大公约数intGCD(intx,inty){intt;while(y>0){t=x%y;x=y;y=t;}returnx;}2.Prime素数判断boolis_prime(intu){if(u==011u==1)returnfalse;if(u==2)returntrue; 16if(u%2==0)returnfalse;for(inti=3;i<=sqrt(u);i+=2)if(u%i==O)returnfalse;returntrue;}1.SievePrime素数筛法constintM=1000;//M:sizeboolmark[M];//true:primenumbervoidsieve_prime(){memset(mark,true,sizeof(mark));mark[0]=mark[l]=false;for(inti=2;i<=sqrt(M);i++){if(mark[i]){for(intj 171.ChineseRemainderTheorem中国余数定理//x=b[i](modw[i])zie[1,len-1]//前提条件w[i]>0,且w□中任意两个数互质intchinese_remainder(intb口,intw口,intlen){inti,d,x,y,m,n;ret=0;n=1;for(i=0;i 18voidcal_prime(){inti,j;memset(numzfalse,sizeof(num));total=0;for(i=2;i<1100;i++){if(!num[i]){prime[total++]=i;j=i+i;while(j<1100){num[j]=true;j+=i;}}}}voidcal_farey(){inti,j,k;inc[l]=1;for(i=2;i 19",f[n]);}}1.Farey序列构造〃构造5000以内的Farey序列constintMAX=8000000;inttotal;intnzk;intfarey[2][MAX];voidmake_farey_seq(intxl,intyljntx2,inty2){if(xl+x2>n11yl+y2>n)return;make_farey_seq(x1,yl,xl+x2,yl+y2);total++;farey[0][total]=xl+x2;farey[l][total]=yl+y2;make_farey_seq(xl+x2zyl+y2,x2,y2);}intmain(){intt;scanf("%d%d"z&nz&t);total=l;farey[0][l]=0;farey[l][l]=1;make_farey_seq(04,1/1);farey[0][total+1]=l;farey[l][total+l]=1;total++;while(t-){scanf("%d"z&k);if(k>total)puts("NoSolution");elseprintf(,,%d/%d 20"/farey[0][k]zfarey[l][k]);}}2.Miller_Rabbin素数测试,Pollard_rho因式分解typedef_int64164;constchar*pformat=n%I64d";164big_rand(I64m){164x=rand();x*=rand();if(x<0)x=-x;returnx%=m;}//x*y%n164mod_mul(I64x,164yz164n){if(x==011y==0)return0;return(((x&l)*y)%n+(mod_mul(x>>lzyzn)< 21boolMiller_Rabbin(I64n){//O(times*(logN)A3)164i,j,x,m,k;if(n==2)returntrue;if(n<211!(n&l))returnfalse;m=n-1;k=0;while(!(m&l))m>>=1,k++;//binaryscanfor(i=0;i<4;i++){//testtimesx=big_rand(n-2)+2;x=mod_exp(xzm,n);if(x==1)continue;for(j=0;j 22if(Miller_Rabbin(n))puts("Prime");else{if(!(n&l))puts("2");else{for(minfac=3;minfac 23if(vl!=v2){sum+=edges[i].w;〃注意sum初始为0point[vl]=v2;j++;}i++;}}intmain(){intkjzj;cin>>n;k=0;while(n!=0){sum=0;k++;for(i=0;i 24,,/k);//cout< 25",sum);〃输Hlsumcin>>n;if(n!=0)printf(" 26");}}1.最小生成树(Prim算法)*FunctionName:最小生成树(Prim算法)*Description:ZJU1203SwordfishO(NA2)#include 27for(j=0;j 28”,sum);cin>>n;if(n!=O)printf(" 29");}}1.单源最短路径(Bellman-ford算法)structnode{inte,v;node(inta=Ozintb=0):e(a),v(b){)};vector 30queue 31cout< 32intnet[NMAX][NMAX];intpath[NMAX],n;intbfs(){queue 33voidinit_preflow(){inti;memset(highzOzsizeof(high));memset(earnzOzsizeof(earn));while(!SQ.empty())SQ.pop();high[O]=n+l;for(i=l;i<=n;i4-+){if(net[O][i]>0){earn[i]=net[0][i];earn[0]-=net[0][i];net[i][0]=net[0][i];net[0][i]=0;if(i!=n)SQ.push(i);}}}inthigh_label_preflow_push(){intij;init_preflow();while(!SQ.empty()){intoverp=SQ.front();SQ.pop();discharge(overp);}returnearn[n];}/*网络中求最大流Dinic算法O(V人2E)适用于稠密图,实际复杂度低于HLPP模板参数含义:n代表网络中节点数,第节点为源点,第n节点为汇点net代表网络,使用前向星表示法存储边dis口代表从源点出发的距离标号path□代表模拟栈中的路径信息cur□代表模拟栈的现场保存返回值:最大流量*/constintNMAX=21000;constintMMAX=250000< 34#defineempty_que2(qf[qnowAl]>=qe[qnowAl])#definesize_que2(qe[qnowAl]-qf[qnowAl])intnzm;intdis[NMAX];intpath[NMAX],deep;intcur[NMAX];boolbfs(){inti,j;memset(disz-l/Sizeof(dis));dis[0]=0;qnow=0;switch_que;push_que(0);switch_que;while(!empty_que2){intI=size_que2;while(I—){intu=pop_que2;for(i=net.start[u];i!=ENDFLAG;i=net.arc[i].next){intv=net.arc[i].v;if(dis[v]==-l&&net.arc[i].cap>net.arc[i].flow){push_que(v);dis[v]=dis[u]+l;if(v==n)returntrue;}}}switch_que;}returnfalse;}intDinic(){intj;intu;intmaxflow=0;while(bfs()){memcpy(curznet.startzsizeof(cur));for(deep=u=O;true;){if(u==n){intneck=INT_MAX,pos;for(i=0;i 35参数含义:n代表网络中的总节点数,第0节点为源点,第n节点为汇点net□□代表剩余网络cost□口代表单位费用path□保存增广路径ecost□源点到各点的最短路算法:初始最小费用和最大流均为0,寻找单位费用最短路在最短路中求出最大流,即为增广路,再修改剩余网络,直到无可增广路为止返回值:最小费用,最大流量constintNMAX=210;intnet[NMAX][NMAX],cost[NMAX][NMAX];intpath[NMAX]zecost[NMAX];intn;boolbellman_ford(){intiJ;memset(pathz-1Zsizeof(path));fill(ecostzecost+NMAX,INT_MAX);ecost[0]=0;boolflag=true;while(flag){flag=false;for(i=0;i<=n;i++){if(ecost[i]==INT_MAX)continue;for(j=0;j<=n;j++){if(net[i][j]>0&&ecost[i]+cost[i][j] 36EDGE(int_u=OJnt_v=0,int_c=0,int_ct=OJnt_f=0):u(_u),v(_v),c叩(_c),flow(_f),8st(_ct){}};constintENDFLAG=-1;structEDGELIST{intstart[NMAX];intlast[NMAX];inttot;EDGEarc[MMAX];voidclear(){tot=ENDFLAG+l;memset(last,ENDFLAG,sizeof(last));}voidpush_back(EDGEedge){edge.next=ENDFLAG;arc[tot]=edge;if(last[edge.u]!=ENDFLAG)arc[last[edge.u]].next=tot;elsestart[edge.u]=tot;last[edge.u]=tot;tot++;}//创建双向弧voidadd_arc(EDGEedge){push_back(edge);push_back(EDGE(edge.vzedge.uzO,INF));}}net;intque[2][NMAX];intqf[2],qe[2]zqnow;#definepush_que(a)(que[qnow][qe[qnow]++]=(a))#definepop_que2(que[qnowAl][qf[qnowAl]++])#defineswitch_queqnowA=1;\qf[qnow]=qe[qnow]=0;#defineempty_que2(qf[qnowAl]>=qe[qnowAl])#definesize_que2(qe[qnowAl]-qf[qnowAl])boolSPFA(){intiJ;bitset 37参数含义:s为源点,d为汇点返回值:网络最大流调用函数前的初始化工作:ver置为网络中节点的个数,代表节点i到节点j的流量,vl[i]存放i与相邻的所有节点其它全局变量均初始化为零*/constintVEX=405;〃网络中顶点数constintHMAX=810;〃最大高度的定义,只要大厂顶点的2倍就可以「intf[VEX][VEX];〃流量intc[VEX][VEX];〃边最大容量inth[VEX];〃节点高度inte[VEX];〃节点容量intver;〃节点数Flvector 38*Description:PKU1419GraphColoring*团:指G的一个完全子图,该子图不包含在任何其他的完全子图当中*最大独立集:补图的最大团*最大团:指其中包含顶点最多的团#include 39for(j=O;j 40nzmax_clique());printf("%d"zseq[0]);for(i=l;i 41n);}}11.最大二分图匹配(匈牙利算法)*FunctionName:最大二分图匹配(匈牙利算法)*Description:HDOJ2063过山车*二分图:指所有顶点分成集合M和N,M或N中任意两个在同一集合中的点互不相连*匹配:一组边顶点分别在两个集合中,并且任意两条边都没有相同顶点*最大匹配:所能得到的最大的边的个数#include 42"zMax_Match());}}12.带权二分图最优匹配(KM算法)/*带权二分图最优匹配KM算法O(N人4)带权二分图是Kn,n的n阶完全图参数含义:bimap口口代表相等子图,bimap[i][j]表示i和j之间有边tx口,ty□代表交错路径在X和Y上的点lx[]zly口代表X和Y上各点的可行标match[y]=x代表y被x匹配w□□权值返回值:最大权和*/ 43constintNMAX=310;boolbimap[NMAX][NMAX];booltx[NMAX]zty[NMAX];intlx[NMAX]zly[NMAX];intmatch[NMAX];intw[NMAX][NMAX]zn;booldfs(intpos){inti;for(i=0;i 44intn,m,sccjintorder[NMAX],order_poszid[NMAX];boolvis[NMAX];voiddfs(intpos){inti,j,l;vis[pos]=true;l=path[pos].size();for(i=0;i 4511.无向图割边割点和双连通分量#definemclear(x)memset((x),0,sizeof((x)))constintMAX=5100;intnzmzdeep;vector 46f数组:顶点的结束访问时间表c数组:顶点颜色表0白色-1灰色1黑色p数组:顶点的前驱表I数组:顶点的L值(最顶层的祖先层数)b数组:顶点的度数表关于标号函数LOW。LOW(U)代表的是与U以及U的子孙直接相连的结点的最高辈分(深度)d[U]U苜次被访问时LOW[U]=min(LOW[U],d[W])访问边{U,W}min(LOW[U],LOW[S])U的儿子S的关联边全部被访问时constintmaxn=100;intn,g[maxn][maxn],gc[maxn][maxn];intd[maxn],f[maxn],l[maxn],p[maxn],c[maxn],b[maxn];inttime;voiddfs_visit(intu){〃递归搜索以U为根的深度优先树intv;c[u]=-1;〃置顶点为灰色〃去抻这句之后适用于仃向图(后血设置不可访问亦⑷time++;d[u]=time,l[u]=time;for(v=1;v<=n;v++)if(g[u][v]>0)if(c[v]==0){〃如果v是白色节点g[v][u]=-1;〃不可再访问gc[u][v]=1;〃树枝边b[u]++;〃度数p[v]=u;〃记录父亲节点dist_visit(v);〃递UI搜索以v为根的深度优先树if(l[v] 47path原图pre保存最小入弧的权del表示被缩去的点fpre保存最小树形图的逆路径例题:TJU2248ChannelDesign*/constintNMAX=110;constintINF=0x7f7f7f7f;intn;intpath[NMAX][NMAX];intpre[NMAX];boolvis[NMAX]zdel[NMAX];intmin_cost;intfold[NMAX]zfpre[NMAX];voiddfs(intpos){inti;vis[pos]=true;for(i=l;i<=n;i++){if(path[pos][i]!=INF&&!vis[i])dfs⑴;}}boolis_connect(introot){inti;memset(visz0zsizeof(vis));dfs(root);for(i=l;i<=n;i++){if(!vis[i])returnfalse;}returntrue;}//O(NA3)boolmin_tree_graph(introot){inti,jzk;//makesureeverynode(exceptroot)havein-arcif(!is_connect(root))returnfalse;memset(delz0,sizeof(del));min_cost=0;for(i=0;i<=n;i++)fold[i]=fpre[i]=i;while(true){for(i=l;i<=n;i++) 48for(i=l;i<=n;i++)vis[fpre[i]]=true;for(i=l;i<=n;i++){if(!vis[i]){intpos=i;while(pos!=root){printf("%d<-pos);pos=fpre[pos];}printf("%d 49"zroot);}}}intmain(){inti/m;while(scanf(H%d%d"z&n,&m),!(n==0&&m==0)){memset(pathz0x7fzsizeof(path));while(m-){intx,y,z;scanf("%d%d%d",&xz&yz&z);path[x][y]=min(path[x][y],z);}if(!min_tree_graph(1))puts(nimpossiblen);elseprintf("%d 50",min_cost);}}17.最小树形图O(VE)constintNMAX=1500;constintINF=0x7f7f7f7f;structLINKT{intls;intadj[NMAX];voidclear(){Is=0;}intoperator[](constintpos){returnadj[pos];}intsize(){returnIs;}voidpush_back(constintpos){adj[ls++]=pos;}};intn;intpath[NMAX][NMAX];LINKTepath[NMAX]znepath[NMAX];intpre[NMAX];boolvis[NMAX]zdel[NMAX];intmin_cost;intfold[NMAX]zfpre[NMAX];voiddfs(intpos){inti;vis[pos]=true;for(i=0;i 51if(j==root)continue;//nocyclei=j;//cyclebeginnodemin_cost+=path[pre[i]][i];for(j=pre[i];j!=i;j=pre[j]) 52//多边形的周长//判断点是否在线段上//判断两条线断是否相交,端点重合算相交//判断两条线断是否平行//判断两条直线断是否相交//直线相交的交点//判断是否简单多边形//求多边形面积//判断是否在多边形上//判断是否在多边形内部//点阵的凸包,返回一个多边形//最近点对的距离#include 53cp.x=pO.x+s*(p2.y-pl.y)/d;cp.y=pO.y-s*(p2.x-pl.x)/d;returnAbs(s);}//返回直线Ax+By+C=0的系数voidCoefficient(constLINE&L,TYPE&A,TYPE&B,TYPE&C){A=L.b.y-L.a.y;B=L.a.x-L.b.x;C=L.b.x*L.a.y-L.a.x*L,b.y;}voidCoefficient(constPOINT&pzconstTYPEa,TYPE&A,TYPE&B,TYPE&C){A=Cos(a);B=Sin(a);C=-(p.y*B+p.x*A);}//线段structSEG{POINTa;POINTb;SEG(){};SEG(POINT_a-zPOINT_b_):a(_aJzb(_b_){};};//圆structCIRCLE 54case0:edge.a=rect.ajedge.b=POINT(rect.b.xzrect.a.y);break;case1:edge.a=POINT(rect.b.xzrect.a.y);edge.b=rect.b;break;case2:edge.a=rect.b;edge.b=POINT(rect.a.xzrect.b.y);break;case3:edge.a=POINT(rect.a.x,rect.b.y);edge.b=rect.a;break;default:break;}returnedge;}TYPEArea(constRECT&rect){return(rect.b.x-rect.a.x)*(rect.b.y-rect.a.y);}//两个矩形的公共面积TYPECommonArea(constRECT&AzconstRECT&B){TYPEarea=0.0;POINTLL(Max(A.a.x,Bax),Max(A.a.yzB.a.y));POINTUR(Min(A.b.xzB.b.x),Min(A.b.y,B.b.y));if((LL.x<=UR.x)&&(LL.y<=UR.y)){area=Area(RECT(LLzUR));}returnarea;}//多边形,逆时针或顺时针给出x,ystructPOLY{intn;//n个点TYPE*x;//xzy为点的指针,首尾必须重合TYPE*y;POLY():n(0),x(NULL)zy(NULL){};POLY(int_n_,constTYPE*_x_,constTYPE*_y_){n=_n_;x=newTYPE[n+l];memcpy(xz_x_,n*sizeof(TYPE));x[n]=_x」0];y=newTYPE[n+1];memcpy(y,_y_,n*sizeof(TYPE));y[n]=多边形顶点POINTVertex(constPOLY&poly,intidx){idx%=poly.n;returnPOINT(poly.x[idx]zpoly.y[idx]);}〃多边形的边SEGEdge(constPOLY&poly,intidx){idx%=poly.n;returnSEG(POINT(poly.x[idx]zpoly.y[idx])zPOINT(poly.x[idx+1],poly.y[idx+1]));}〃多边形的周长TYPEPerimeter(constPOLY&poly){TYPEp=0.0;for(inti=0;i 55(((p.x-seg.a.x)*(p.x-seg.b.x)<011(p.y-seg.a.y)*(p.y-seg.b.y)<0)&&(IsEqual(Cross(seg.bzpzseg.a),0)));}〃判断两条线断是否相交,端点重合算相交boolIslntersect(constSEG&uzconstSEG&v){return(Cross(v.azu.bzu.a)*Cross(u.bzv.b,u.a)>=0)&&(Cross(u.azv.bzv.a)*Cross(v.bzu.b,v.a)>=0)&&(Max(u.a.xzu.b.x)>=Min(v.a.x,v.b.x))&&(Max(v.a.xzv.b.x)>=Min(u.a.xzu.b.x))&&(Max(u.a.yzu.b.y)>=Min(vay,v.b.y))&&(Max(v.a.yzv.b.y)>=Min(u.a.y,u.b.y));}〃判断两条线断是否平行boolIsParallel(constLINE&A,constLINE&B){TYPEAl,Bl,Cl;TYPEA2,B2fC2;Coefficient(A,Al,Bl,Cl);CoefficientB,A2ZB2,C2);return(A1*B2==A2*B1)&&((A1*C2!=A2*Cl)||(Bl*C2!=B2*Cl));}〃判断两条直线断是否相交boolIslntersect(constLINE&A,constLINE&B){return!IsParallel(AzB);}〃直线相交的交点POINTIntersection(constLINE&AzconstLINE&B){TYPEAlzBl,C1;TYPEA2,B2,C2;CoefficientA,Al,Bl,Cl);Coefficient(BzA2ZB2,C2);POINT1(0,0);Lx=-(B2*Cl-Bl*C2)/(Al*B2-A2*Bl);I.y=(A2*Cl-Al*C2)/(Al*B2-A2*Bl);returnI;}boolIsInCircle(constCIRCLE&circle,constRECT&rect){return(circle.x-circle.r>=rect.a.x)&&(circle.x+circle.r<=rect.b.x)&&(circle.y-circle.r>=rect.a.y)&&(circle.y+circle.r<=rect.b.y);}〃判断是否简单多边形boolIsSimple(constPOLY&poly){if(poly.n<3)returnfalse;SEGLI,L2;for(inti=0;i 56{if(IsOnSeg(Edge(polyzi),p))returntrue;}returnfalse;}〃判断是否在多边形内部boolIsInPoly(constPOLY&poly,constPOINT&p){SEGL(p,POINT(Infinityzp.y));intcount=0;for(inti=0;i 57doubleClosestPairDistance(intstart,intend){intm=end-start+l,mid,i;doubletlzt2,dis=-l,t;if(m<=3){for(i=start;i 58all=2*(x3-x2);al2=2*(y3-y2);a21=2*(x2-xl);a22=2*(y2-yl);bl=x3*x3-x2*x2+y3*y3-y2*y2;b2=x2*x2-xl*xl+y2*y2-yl*yl;d=all*a22-al2*a21;dl=bl*a22-al2*b2;d2=all*b2-bl*a21;〃x,y是圆心坐标x=dl/d;y=d2/d;return(xl-x)*(xl-x)+(yl-y)*(yl-y);}1.三角形几个重要的点设三角形的三条边为a,b,c,且不妨假设a<=b<=c三角形的面积可以根据海伦公式算得,如下:s=sqrt(p*(p-a)*(p-b)*(p-c)),p=(a+b+c)/21.费马点(该点到三角形三个顶点的距离之和最小)有个有趣的结论:若三角形的三个内角均小于120度,那么该点连接三个顶点形成的三个角均为120度;若三角形存在一个内角大于120度,则该顶点就是费马点)计算公式如下:若有一个内角大于120度(这里假设为角C),则距离为a+b若三个内角均小于120度,则距离为sqrt((a*a+b*b+c*c+4*sqrt(3.0)*s)/2),其中2.内心----角平分线的交点☆x=(a+b-c)/2,y=(a-b+c)/2,z=(-a+b+c)/2,h=s/p计算公式为sqrt(x*x+h*h)+sqrt(y*y+h*h)+sqrt(z*z+h*h)3.重心----中线的交点计算公式如下:2.0/3*(sqrt((2*(a*a+b*b)-c*c)/4)+sqrt((2*(a*a+c*c)-b*b)/4)+sqrt((2*(b*b+c*c)-a*a)/4))4.垂心垂线的交点计算公式如下:5*(c/2/sqrt(l-cosC*cosC))第七章专题讨论1.树状数组 59*FunctionName:树状数组*Description:HDOJ1166敌兵布阵*减少冗余统计,是线段树的•种变化#include 60",i);while(scanf(H%s",buffer)==1&&buffer[O]!='E'){scanf("%d%d"z&a,&b);switch(buffer[O]){case,Q':printf(,'%d 61H/sum(b)-sum(a)+data[a]);break;case'A':plus(a,b,n);data[a]+=b;break;case'S':plus(az-b,n);data[a]-=b;break;}}}}2.字典树*FunctionName:字典树(多路杳找树)*Description:HDOJ1075WhatAreYouTalkingAbout*易于字符保存,插入和查找,时间复杂度都是线性#include 62else{t=newnode();s->next[x[i]-'a']=t;s=t;}}//fors->index=pos;}voiddeltrie(trie*s){inti;for(i=0;i<26;i++){if(s->next[i])deltrie(s->next[i]);}free(s);s=NULL;}intfind(trie*szcharx[]){inti;if(x[0]==0)return-1;for(i=0;x[i];i++){if(s->next[x[i]-'a'])s=s->next[xtij-'a*];elsebreak;}if(x[i]==0)returns->index;elsereturn-1;}intmain(){inttznjJ,all;charword[20]zmars[20],ch;thead=newnode();while(scanf("%s,,/word)==l)if(word[0]=='S')break;i=l;while(scanf("%s"zdic[i])==l&&dic[i][0]!=,E'){scanf("%s",mars);insert(thead,marszi);i+4-;}all=i;while(scanf("%s",word)==l)if(word[0]=='S')break;getchar();j=0;while(scanf("%c"z&ch)==l&&ch!=E){if(ch>='a'&&ch<=*z'){mars[j]=ch;j++;}else{mars[j]=O;t=find(thead,mars);j=0;if(t>0)printf(H%sHzdic[t]);elseif(mars[O]!=O)printf(n%s,,/mars);printf("%c"zch);}}//whiledeltrie(thead);}3.后缀树*Description:PKU2774LongLongMessage*有效的支持字符串匹配和查询#include 63#defineNUM27#defineSTARTCHAR'a,#defineSPECIALCHAR#defineERROR-1#defineTYPE11#defineTYPE22#defineLEAF1#defineNOTLEAF2structSuffixTrie{intStart,End;SuffixTrie*Next[NUM];SuffixTrie*Link;SuffixTrie*Father;intFlag;intLength;};charstr[100010],buf[100010];SuffixTriehead;SuffixTrie*P,*G,*U,*VZ*q;intW[3],len,Ien2;voidCreateNode(SuffixTrie*&Node){inti;Node=(SuffixTrie*)malloc(sizeof(SuffixTrie));Node->Start=Node->End=Node->Length=ERROR;for(i=0;i 64posend=Node->Next[s[start]-STARTCHAR]->End;for(i=posbegin;i<=posend;i++){if(s[i]!=s[start+i-posbegin])break;}if(i==posend+1){returnInsert(Node->Next[s[start]-STARTCHAR]zstart+i-posbeginzs);}else{CreateNode(t);t->Start=posbegin;t->End=i-1;t->Flag=NOTLEAF;Node->Next[s[start]-STARTCHAR]->Start=i;t->Next[s[i]-STARTCHAR]=Node->Next[s[start]-STARTCHAR];t->Next[s[i]-STARTCHAR]->Father=t;Node->Next[s[start]-STARTCHAR]=t;t->Father=Node;t->Length=Node->Length+t->End-t->Start+l;Insert(tzstart+i-posbegin,s);G=Node;P=t;returnTYPE2;}}}intSelect(intstart,chars[]zinttype){intresultl,result2zresult;if(type==TYPE1){U=P->Link;result=Insert(Uzstart+U->Lengthzs);}else{U=G->Link;if(G->Link==G){W[0]=P->Start+l;W[l]=P->End;W[2]=P->End-P->Start;}else{W[0]=P->Start;W[l]=P->End;W[2]=P->End-P->Start+1;}if(W[2]==0){V=G;P->Link=V;result=Insert(Vzstart,s);}else{resultl=FindV(s);result2=Insert",start+V->Length,s);if(resultl==TYPE2){G=P->Father;result=resultl;}elseresult=result2;}}returnresult;}voidBuildSuffixTrie(SuffixTrie&hzchars[]){inti;inttype;len=strlen(s);CreateNode(h.Next[s[0]-STARTCHAR]);h.Next[s[O]-STARTCHAR]->Start=O;h.Next[s[O]-STARTCHAR]->End=len-l;h.Next[s[O]-STARTCHAR]->Father=&h;h.Next[s[O]-STARTCHAR]->Length=h.Length+h.Next[s[O]-STARTCHAR]->End-h.Next[s[O]-STARTCHAR]->Start+l;h.Flag=NOTLEAF;type=TYPE1;P=&h;for(i=1;i 65P=P->Link;returnresult;}intSearch(SuffixTrie&hzchars[]){intresultjinti;inttemp;Ien2=strlen(s);result=0;P=&head;for(i=0;i 66"/result);}}4.线段树*FunctionName:线段树*Description:HDOJ1542Atlantis*用于表示区间线段#include 67itree_splite(pList,pParent->pLChild,iLeft,iMid);itree_splite(pListzpParent->pRChild,iMid,iRight);}PITREE_NODEitree_generate(constdouble*pList,constintiListCount){PITREE_NODEpRoot=newITREE_NODE;memset(pRootz0,sizeof(ITREE_NODE));pRoot->left=pList[O];pRoot->right=pList[iListCount-1];itree_splite(pList,pRoot,0,iListCount-1);returnpRoot;}voiditree_destroy(PITREE_NODEpParent){if(pParent==NULL)return;if(pParent->pLChild)itree_destroy(pParent->pLChild);if(pParent->pRChild)itree_destroy(pParent->pRChild);deletepParent;}inlinevoiditree_measure(PITREE_NODEpNode){if(pNode->count>0)pNode->measure=pNode->right-pNode->left;elseif(pNode->pLChild&&pNode->pRChild)pNode->measure=pNode->pLChild->measure+pNode->pRChild->measure;elsepNode->measure=0;}inlinevoiditreeJines(PITREE_NODEpNode){if(pNode->count>0){pNode->lines=1;}elseif(pNode->pLChild&&pNode->pRChild){if(pNode->pLChild->rbound&&pNode->pRChild->Ibound){pNode->lines=pNode->pLChild->lines+pNode->lines-1;}else{pNode->lines=pNode->pLChild->lines+pNode->lines;}}else{pNode->lines=0;}}//插入的时候value=1,删除的时候value=-1voiditree_update(PITREE_NODEpParentzconstdoubleleft,constdoublerightJntvalue){if(pParent->left==left&&pParent->right==right){safe_add(pParent->count,value);safe_add(pParent->Ibound,value);safe_add(pParent->rbound,value);itree_measure(pParent);itree_lines(pParent);}else{if(pParent->pLChild->right>left){if(pParent->pLChild->right>=right){itree_update(pParent->pLChild,left,right,value);}else{itree_update(pParent->pLChild,leftzpParent->pLChild->rightzvalue);itree_update(pParent->pRChild,pParent->pRChild->left:,right,value);}}else{itree_update(pParent->pRChild,left,right,value);}itree_measure(pParent);itree_lines(pParent);if(left==pParent->left)safe_add(pParent->Ibound,value);if(right==pParent->right){safe_add(pParent->rboundzvalue);}}}voiditree_insert(PITREE_NODEpParent,constdoubleleft,constdoubleright){itree_update(pParent,left,right,1);}voiditree_delete(PITREE_NODEpParent,constdoubleleft,constdoubleright){itree_update(pParentzleft,right,-1);}structEVENT{doublex,ylzy2;inttype;};boolcmp(constEVENT&a,constEVENT&b){returna.x 68doubleY[200];doubletsize=0.0;intmain(){doublexl,x2,yl,y2;inti,n,n2,cas=0;while(scanf(n%d"z&n)==1&&n){cas++;n2=n<<1;for(i=0;i 69fbtalexploredarea:%.2lf 70 71"zcas,tsize);}return0;}5.并查集*FunctionName:并查集*Description:集合操作,并,除,判断constintMax=1000;typedefintElemlype;intParent[Max],Rank[Max];intFind(intx){inttemp=x,root,w;〃搜寻根节点while(Parent[x]!=0)x=Parent[x];root=x;x=temp;〃压缩路径while(Parent[x]!=0){w=Parent[x];Parent[x]=root;x=w;}returnroot;}intUnion(intx,inty){intuzvzroot;u=Find(x);v=Find(y);if(Rank[u]<=Rank[v]){root=Parent[u]=v;if(Rank[u]==Rank[v])Rank[v]+4-;>elseroot=Parent[v]=u;returnroot;} 725.二叉堆103020/\/\3438_3024*便於寻找父节点和子节点constintMax=1000;typedefintElemlype;ElemlypeHe叩[Max];intSift_Up(inti)//上移{Elemlypetemp;boolflag;flag=true;if(i==1)return0;do{if(Heap[i]>Heap[i/2]){temp=Heap[i];Heap[i]=Heap[i/2];Heap[i/2]=temp;}elseflag=false;i/=2;}while(i>l11flag);return1;}intSift_Down(intijntn)//卜.移{boolflag;Elem7ypetemp;flag=false;if(2*i>n)return0;do{i*=2;if(i+l<=n&&Heap[i+1]>Heap[i])i++;if(Heap[i/2] 735.逆序数(归并排序)*FunctionName:逆序数(归并排序)*Description:N*Log(N)〃逆序数值存放在anti中intp[MAX],t[MAX]zanti=0;voidmerge(intfirst,intlast){intmid=(first+last)/2;intil=0,12=first,i3=mid+1;while(i2<=mid&&i3<=last){if(p[i2]>p[i3]){t[il++]=p[i3++];anti+=mid-i2+l;}elset[il++]=p[i2++];>while(i2<=mid)t[il++]=p[i2++];while(i3<=last)t[il++]=p[i3++];il=first;i2=0;while(i2for(j=0;j
此文档下载收益归作者所有