ACM算法模板.docx

上传人:b****7 文档编号:23775604 上传时间:2023-05-20 格式:DOCX 页数:63 大小:397.81KB
下载 相关 举报
ACM算法模板.docx_第1页
第1页 / 共63页
ACM算法模板.docx_第2页
第2页 / 共63页
ACM算法模板.docx_第3页
第3页 / 共63页
ACM算法模板.docx_第4页
第4页 / 共63页
ACM算法模板.docx_第5页
第5页 / 共63页
点击查看更多>>
下载资源
资源描述

ACM算法模板.docx

《ACM算法模板.docx》由会员分享,可在线阅读,更多相关《ACM算法模板.docx(63页珍藏版)》请在冰豆网上搜索。

ACM算法模板.docx

ACM算法模板

目录

STL2

List3

map3

set3

vector4

queue4

permutation排列函数5

C笔记5

二八十六进制输出5

输入空格5

Ascill表5

操作符重载6

数论7

叉积向量7

最大公约数和最小公倍数gcd7

质数筛法7

大数取模(a^p%m)8

取模(a%b)8

扩展欧几里得(ax+by=gcd(a,b)8

模运算(ax+ny=b-->a*x=bmodn)9

中国剩余定理9

欧拉函数(小于n且和n互质的正整数(包括1)的个数)10

Miller-Rabin素性检测10

大素数判断和素因子分解(miller-rabin,Pollard_rho算法)11

全排序(递归)15

图论15

最小生成树之Kruskal算法(求得全部连通)15

最小生成树之Prim算法(求得全部连通)16

单源最短路径之Dijkstra算法17

单源最短路径之Floyd算法18

二分图最大匹配19

并查集19

字符串20

最长公共子序列20

字符匹配KMP算法20

AC自动机21

回文数Manacher算法24

动态规划,背包问题26

01背包26

完全背包27

多重背包27

混合三种背包28

二维费用的背包问题29

分组的背包问题29

线段树29

划分树31

约瑟夫环34

排序35

分治排序35

快速排序36

堆排序36

拓扑排序39

康托展开(广搜)39

 

STL

greater(),less()

find()函数,找到则返回其下标,没找到则返回最后的下标

chara[]="1548946461";

/*for(i=0;i

a[i]=rand()%10;*/

copy(a,a+strlen(a),ostream_iterator(cout,""));cout<

char*p=find(a,a+strlen(a),'8');

if(p!

=a+strlen(a))

*p='-';

copy(a,a+N,ostream_iterator(cout,""));cout<

copy()函数

doubledarray[10]=

{1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9};

vectorvdouble(10);

vector:

:

iteratoroutputIterator=vdouble.begin();

copy(darray,darray+10,outputIterator);

replace(起始,结束,旧值,新值)替换函数,将[起始,结束]区间中旧值替换成新值

reverse()反转函数

random_shuffle()排序打乱函数

三种插入迭代器

listdList;

vectordVector;

copy(dVector.begin(),dVector.end(),front_inserter(dList));//头插入

·insert()普通插入器将对象插入到容器任何对象的前面。

·front_inserter()将对象插入到数据集的前面——例如,链表表头。

·back_inserter()将对象插入到集合的尾部——例如,矢量的尾部,导致矢量容器扩展

for_each(v.begin(),v.end(),initialize);

voidinitialize(long&ri)

{

ri=(rand()%10-5);

}

vector:

:

iteratorp;

p=find_if(v.begin(),v.end(),isMinus);//调用断言函数

while(p!

=v.end()){

count++;

p=find_if(p+1,v.end(),isMinus);

}

boolisMinus(constlong&ri)

{

return(ri<0);

}

List

it=lis.erase(it);删除当前it返回it的下一个

map

1.插入数据

1.1.用数组插入,有覆盖效果,若key值之前存在覆盖之前的值

mp["t"]=1;

1.2.用insert函数,若之前存在则插入失败

pr=mp.insert(map:

:

value_type("l",2));

pr=mp.insert(pair("l",3));

/*通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话pr.second应该是true的,否则为false。

*/

2.输出

for(it=mp.begin();it!

=mp.end();++it)

cout<first<<""<second<

3.删除数据

3.1.删除一条数据,用关键字删除:

mapStudent.erase(iter);

3.2.删除成片数据mapStudent.earse(mapStudent.begin(),mapStudent.end());

3.3.

4.

set

setst;

pair:

:

iterator,bool>pr;

pr=st.insert(str);

if(pr.second)puts("YES");

vector

#include

表述

c.assign(beg,end)将(beg;end)区间中的数据赋值给c。

c.assign(n,elem)将n个elem的拷贝赋值给c。

c.at(idx)传回索引idx所指的数据,如果idx越界,抛出out_of_range。

c.back()传回最后一个数据,不检查这个数据是否存在。

c.begin()传回迭代器中的第一个数据地址。

c.capacity()返回容器中数据个数。

c.clear()移除容器中所有数据。

c.empty()判断容器是否为空。

c.end()//指向迭代器中末端元素的下一个,指向一个不存在元素。

c.erase(pos)// 删除pos位置的数据,传回下一个数据的位置。

c.erase(beg,end)删除[beg,end)区间的数据,传回下一个数据的位置。

c.front()传回第一个数据。

get_allocator使用构造函数返回一个拷贝。

c.insert(pos,elem)//在pos位置插入一个elem拷贝,传回新数据位置

c.insert(pos,n,elem)//在pos位置插入n个elem数据,无返回值

c.insert(pos,beg,end)//在pos位置插入在[beg,end)区间的数据。

无返回值

c.max_size()返回容器中最大数据的数量。

c.pop_back()删除最后一个数据。

c.push_back(elem)在尾部加入一个数据。

c.rbegin()传回一个逆向队列的第一个数据。

c.rend()传回一个逆向队列的最后一个数据的下一个位置。

c.resize(num)重新指定队列的长度。

c.reserve()保留适当的容量。

c.size()返回容器中实际数据的个数。

c1.swap(c2)//将c1和c2元素互换

swap(c1,c2)//同上操作。

vector//创建一个空的vector

vectorc1(c2)//复制一个vector

vectorc(n)//创建一个vector,含有n个数据,数据均已缺省构造产生

vectorc(n,elem)//创建一个含有n个elem拷贝的vector

vectorc(c1.beg,c2.end)//创建一个以(beg;end)为区间的vector

c.~vector()//销毁所有数据,释放内存

queue

优先队列

priority_queueqi;//默认是从大到小

priority_queue,greater>qi2;//从小到大,其中第二个是参数是容器类型,第三个是比较函数,可以自写,#includegreater头文件

priority_queueq;

structnode

{

intx,y,val;

node(intxx,intyy,intvv):

x(xx),y(yy),val(vv){}

node(){}

};

booloperator<(noded1,noded2)

{

returnd1.val>d2.val;

}

permutation排列函数

在使用时需要sort先数组或者字符串

sort(..,..,cmp)

prev_permutation//从后向前排

sort()

While(next_permutation//从前向后排)

copy(a,a+3,ostream_iterator(cout,""));

cout<

C笔记

二八十六进制输出

cout<(x))<

cout<

cout<

输入空格

scanf("%[^\n]",str);

Ascill表

定义从0到127的一百二十八个数字所代表的英文字母或一样的结果与意义

操作符重载

1.booloperator==(Nodea,Nodeb){

if(a.level==b.level&&a.row==b.row&&a.colunm==b.colunm)

returntrue;

returnfalse;

}

2.structPoint{

intx,y;

Pointoperator-(Pointp2){

Pointp;

p.x=this->x-p2.x;

p.y=this->y-p2.y;

returnp;

}

};

3.Pointoperator+(Pointp1,Pointp2){

p1.x+=p2.x;

p1.y+=p2.x;

returnp1;

}

数论

叉积向量

三角形面积等于两边的向量的叉积:

  设边向量A(x1,y1)B(x2,y2)

则面积Area=1/2(x1*y2-y1*y2)

向量P,向量Q 若A*B==0则说明向量A和B共线。

 A*B=x1*y2-x2*y1;

最大公约数和最小公倍数gcd

intgcd(inta,intb){//最大公约数

intr;

intt=a*b;

while(b>0){

r=a%b;

a=b;

b=r;

}

returna;//最大公约数。

returnt/a;//最小公倍数

}

质数筛法

boolflog[Max];///初始默认为true;

inttemp,index;

for(inti=2;i!

=Max;i++)

{

if(!

flog[i])continue;

//temp=i;

index=i;

while(index

{

flog[index]=false;

index+=i;

}

flog[i]=true;

}

大数取模(a^p%m)

longmodular_exp(longa,longb,longn)//d≡a^bmodn

{

longd=1;

longt=a;

while(b>0)

{

if(b%2==1)

d=(d*t)%n;

b=b/2;

t=(t*t)%n;

}

returnd;

}

取模(a%b)

intmod(inta,intb)

{

if(a>=0)

returna%b;

else

returna%b+b;

}

扩展欧几里得(ax+by=gcd(a,b)

intextended_gcd(inta,intb,int&x,int&y)

{/*a*x1+b*y1=gcd(a,b)=gcd(b,a%b)=b*x2+a%b*y2

=a*y2+b*x2–a/b*b*y2;

则:

x1=y2,y1=x2-(a/b)*y2;(守恒定律) 

当b==0时,x2=1,y2=0;*/

intret,tmp;

if(b==0){

x=1;y=0;returna;

}

ret=extended_gcd(b,a%b,x,y);

tmp=x;

x=y;

y=tmp-a/b*y;

returnret;

}

模运算(ax+ny=b-->a*x=bmodn)

a*x=bmodn

boolmodular_Linear(inta,intb,intn)

{

intx,y,x0,i;

/*

//ax=b(modn)等价于ax+ny=b

我们求得ax+ny=gcd(a,n)那么当gcd(a,n)|b时有解

*/

intd=extended_gcd(a,n,x,y);

if(b%d)

returnfalse;

x0=x*(b/d)%n;

for(i=0;i

printf("%d\n",(x0+i*(n/d))%n);

returntrue;

}

中国剩余定理

intChinese_Remainder(inta[],intw[],intlen)//a[]存放余数,w[]存放两两互质的数

{

inti,d,x,y,m,n,ret;

ret=0;

n=1;

for(i=0;i

n*=w[i];//公倍数

for(i=0;i

{

m=n/w[i];

d=extended_gcd(w[i],m,x,y);//w[i]*x+m*y=gcd(w[i],m)==1

//w[i]=1(modm)

ret=(ret+y*m*a[i])%n;

}

return(n+ret%n)%n;

}

 

欧拉函数(小于n且和n互质的正整数(包括1)的个数)

φ函数的值通式:

φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1,p2……pn为x的所有质因数,x是不为0的整数。

φ

(1)=1(唯一和1互质的数就是1本身)。

(注意:

每种质因数只一个。

比如12=2*2*3)那么φ(12)=12*(1-1/2)*(1-1/3)=4)

若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。

欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n)。

特殊性质:

当n为奇数时,φ(2n)=φ(n),证明与上述类似。

inteular(intn)

{

intret=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;

returnret;

}

递推求得

for(i=1;i<=N;i++)

phi[i]=i;

for(i=2;i<=N;i+=2)

phi[i]/=2;

for(i=3;i<=N;i+=2)

if(phi[i]==i)

for(j=i;j<=N;j+=i)

phi[j]=phi[j]/i*(i-1);//phi[i]*(1-1/i)

Miller-Rabin素性检测

#include

#include

usingnamespacestd;

intWitness(inta,intn)

{

inti,d=1,x;

for(i=ceil/*大于或者等于指定表达式的最小整数*/(log((float)n-1)/log(2.0))-1;i>=0;i--)

{

x=d;

d=(d*d)%n;

if((d==1)&&(x!

=1)&&(x!

=n-1))return1;

if(((n-1)&(1<0)d=(d*a)%n;

}

return(d==1?

0:

1);

}

intMiller_Rabin(intn,ints)

{

intj,a;

for(j=0;j

{

a=rand()*(n-2)/RAND_MAX+1;

if(Witness(a,n))return0;

}

return1;

}

intmain()

{

intn;

while(cin>>n)

if(Miller_Rabin(n,10))

cout<<"YES"<

elsecout<<"NO"<

return0;

}

 

///

大素数判断和素因子分解(miller-rabin,Pollard_rho算法)

//传说中的随机算法。

//效率极高。

//可以对⼀个2^63的素数进行判断。

//可以分解比较大的数的因子。

#include

#include

#include

#include

#include

#include

usingnamespacestd;

//****************************************************************

//Miller_Rabin算法进行素数测试

//速度快,而且可以判断<2^63的数

//****************************************************************

constintS=20;//随机算法判定次数,S越大,判错概率越小

//计算(a*b)%c.a,b都是longlong的数,直接相乘可能溢出的

//a,b,c<2^63

longlongmult_mod(longlonga,longlongb,longlongc)

{

a%=c;

b%=c;

longlongret=0;

while(b)

{

if(b&1){ret+=a;ret%=c;}

a<<=1;

if(a>=c)a%=c;

b>>=1;

}

returnret;

}

//计算x^n%c

longlongpow_mod(longlongx,longlongn,longlongmod)//x^n%c

{

if(n==1)returnx%mod;

x%=mod;

longlongtmp=x;

longlongret=1;

while(n)

{

if(n&1)ret=mult_mod(ret,tmp,mod);

tmp=mult_mod(tmp,tmp,mod);

n>>=1;

}

returnret;

}

//以a为基,n-1=x*2^ta^(n-1)=1(modn)验证n是不是合数

//⼀定是合数返回true,不⼀定返回false

boolcheck(longlonga,longlongn,longlongx,longlongt)

{

longlongret=pow_mod(a,x,n);//(a^x)%n

longlonglast=ret;

for(inti=1;i<=t;i++)

{

ret=mult_mod(ret,ret,n);//二次探测定理,ret^2%n==1,那么ret=1,n-1

if(ret==1&&last!

=1&&last!

=n-1)returntrue;//合数

last=ret;

}

if(ret!

=1)returntrue;

returnfalse;

}

//Miller_Rabin()算法素数判定

//是素数返回true.(可能是伪素数,但概率极小)

//合数返回false;

boolMiller_Rabin(longlongn)

{

if(n<2)returnfalse;

if(n==2)returntrue;

if((n&1)==0)returnfalse;//偶数

longlongx=n-1;

longlongt=0;

while((x&1)==0){x>>=1;t++;}

for(inti=0;i

{

longlonga=rand()%(n-1)+1;//rand()需要stdlib.h头文件

if(check(a,n,x,t))

re

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1