#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<ctime>
#include<cstdlib>
#include<algorithm>
using namespace std;
/*对拍
@echo off
:loop
数据.exe
a.exe
b.exe
fc a.out b.out
if not errorlevel 1 goto loop
pause
goto loop
*/
int read(){//读入优化
int ans=0,f=1;char ret=getchar();
while(ret>'9'||ret<'0') f=(ret=='-')?-1:1,ret=getchar();
while(ret<='9'&&ret>='0') ans=(ans<<1)+(ans<<3)+ret-'0',ret=getchar();
return ans;
}
int fastpow(int x,int k,int p){//快速幂
int ans=1;
while(k){
ans=(1ll*ans*(k&1)?a:1)%p;
a=1ll*a*a%p;
k>>=1;
}
return ans;
}
int gcd(int a,int b){//最大公约数
if(!b) return a;
if(f[a][b]) return f[a][b];
return f[a][b]=gcd(b,a%b);
}
int fmny(int x,int p){//费马小定理求逆元,p与x互质
return fastpow(x,p-2,p);
}
int exgcd(int &x,int &y,int a,int b){//扩展欧几里得 求逆元
if(!b) {
x=1,y=0;
return a;
}
int ret=gcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return ret;
}
void prepare(){//素数线性筛+欧拉线性筛
phy[1]=1;ip[1]=1;
for(int i=2;i<=10000000;i++){
if(!ip[i]){
pr[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&i*pr[j]<=10000000;j++){
ip[pr[j]*i]=1;
int s=0;
if(i%pr[j]) s=1;
phy[i*pr[j]]=phy[i]*(pr[j]-s);
if(!s) break;
}
}
} //数论
void add(int x,int y,int z){ //邻接链表
nex[++tot]=head[x];
to[tot]=y;
cos[tot]=z;
head[x]=tot;
}
void floyed(){ //弗洛伊德 O(n^3)求多源最短路
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&j!=k&&i!=k)
dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
}
void spfa(){ //spfa O(N*K)求单源最短路
while(!q.empty()){
int x=q.front();q.pop();vis[x]=0;
for(int i=head[x];i;i=nex[i]){
int tmp=to[i];
if(dis[tmp]>dis[x]+cos[i]){
dis[tmp]=dis[x]+cos[i];
if(!vis[tmp]) vis[tmp]=1,q.push(tmp);
}
}
}
}
void dijsitla(){
for(int i=1;i<=n;i++){
node t=q.top();
q.pop();
}
}
void tarjan(int x){
dfn[x]=++cnt;
low[x]=cnt;
for(int head[x];)
}
void sort(int l,int r){//归并排序
if(l==r) return;
int mid=(l+r)>>1;
sort(l,mid);
sort(mid+1,r);
int t1=l,t2=mid+1,tot=l;
for(;tot<=r;){
if((a[t1]<=a[t2]&&t1<=mid)||t2>r) tmp[tot++]=a[t1++];
else if(t1>mid||(a[t2]<a[t1]&&t2<=r))tmp[tot++]=a[t2++];
}
for(int i=l;i<=r;i++) a[i]=tmp[i];
}
int main(){
}
数状数组模板
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,m,x,y,b[1100000],opt;
void add(int i,int k){
for(;i<=n;i+=i&-i)
b[i]+=k;
}
int ask(int i){
int ans=0;
for(;i;i-=i&-i)
ans+=b[i];
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&x),add(i,x);
while(m--){
scanf("%d%d%d",&opt,&x,&y);
if(opt==1) add(x,y);
else printf("%d\n",ask(y)-ask(x-1));
}
}
RMQ模板st表
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,m,st[110000][21],l,r;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&st[i][0]);
for(int k=1;(1<<k)<=n;k++)
for(int i=1;i<=n;i++)
if(i+(1<<k-1)<=n)
st[i][k]=max(st[i][k-1],st[i+(1<<k-1)][k-1]);
while(m--){
scanf("%d%d",&l,&r);
int ans=0;
for(int k=20;k>=0;k--)
if(l+(1<<k)-1<=r) ans=max(ans,st[l][k]),l+=(1<<k);
printf("%d\n",ans);
}
}
线段树区间修改与查询模板
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
#define ll long long
using namespace std;
int n,m,l,r,opt;ll b[510000],k;
struct Node{
ll s,add;
}tr[2100000];
void built(int o,int l,int r){
if(l==r) scanf("%lld",&tr[o].s);
else {
int mid=(l+r)>>1;
built(o<<1,l,mid);
built(o<<1|1,mid+1,r);
tr[o].s=tr[o<<1].s+tr[o<<1|1].s;
}
}
void pushdown(int o,int len1,int len2){
tr[o<<1].add+=tr[o].add;
tr[o<<1|1].add+=tr[o].add;
tr[o<<1].s+=tr[o].add*len1;
tr[o<<1|1].s+=tr[o].add*len2;
tr[o].add=0;
return ;
}
void add(int o,int l,int r,int ql,int qr,ll ins){
int mid=(l+r)>>1,len2=r-mid,len1=mid-l+1,len=r-l+1;
if(l>qr||r<ql) return ;
if(l>=ql&&r<=qr) {
tr[o].add+=ins;
tr[o].s+=ins*len;
return ;
}
if(tr[o].add) pushdown(o,len1,len2);
add(o<<1,l,mid,ql,qr,ins);
add(o<<1|1,mid+1,r,ql,qr,ins);
tr[o].s=tr[o<<1].s+tr[o<<1|1].s;
}
ll ask(int o,int l,int r,int ql,int qr){
int mid=(l+r)>>1,len2=r-mid,len1=mid-l+1;
if(l>qr||r<ql) return 0;
if(l>=ql&&r<=qr)
return tr[o].s;
if(tr[o].add) pushdown(o,len1,len2);
return ask(o<<1,l,mid,ql,qr)+ask(o<<1|1,mid+1,r,ql,qr);
}
int main(){
scanf("%d%d",&n,&m);
built(1,1,n);
while(m--){
scanf("%d%d%d",&opt,&l,&r);
if(opt==1) scanf("%lld",&k),add(1,1,n,l,r,k);
else printf("%lld\n",ask(1,1,n,l,r));
}
}
hash暴力匹配字符串
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
#define p 1000000009
using namespace std;
char a[1100000],b[1100000];
int pow[1100000],hasha[1100000],hashb,Next[1100000];
void getnext(char *b,int m,int *Next){
int j=0;
for(int i=2;i<=m;i++){
while(j&&b[i]!=b[j+1]) j=Next[j];
if(b[i]==b[j+1]) j++;
Next[i]=j;
}
}
int main(){
cin>>a+1>>b+1;
int lena=strlen(a+1),lenb=strlen(b+1);
pow[1]=1;
for(int i=2;i<=max(lena,lenb);i++) pow[i]=1ll*pow[i-1]*29%p;
for(int i=1;i<=lena;i++)
hasha[i]=(1ll*hasha[i-1]*29+a[i]-'A')%p;
for(int i=1;i<=lenb;i++)
hashb=(1ll*hashb*29+a[i]-'A')%p;
for(int i=1;i+lenb-1<=lena;i++){
int has=(1ll*hasha[i+lenb-1]-1ll*pow[lenb]*hasha[i]%p+p)%p;
if(has==hashb) printf("%d\n",i);
}
getnext(b,lenb,Next);
for(int i=1;i<=lenb;i++) printf("%d ",Next[i]);
}
kmp匹配字符串
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
#define p 1000000009
using namespace std;
char a[1100000],b[1100000];
int pow[1100000],hasha[1100000],hashb,Next[1100000];
void Get_next(char *b,int m,int *Next){
int j=0;
for(int i=2;i<=m;i++){
while(j&&b[i]!=b[j+1]) j=Next[j];
if(b[i]==b[j+1]) j++;
Next[i]=j;
}
}
void KMP(char *a,char *b,int n,int m,int *Next){
int j=0;
for(int i=1;i<=n;i++){
while(j&&a[i]!=b[j+1]) j=Next[j];
if(a[i]==b[j+1]) j++;
if(j==m) printf("%d\n",i-j+1),j=Next[j];
}
}
int main(){
cin>>a+1>>b+1;
int lena=strlen(a+1),lenb=strlen(b+1);
Get_next(b,lenb,Next);
KMP(a,b,lena,lenb,Next);
for(int i=1;i<=lenb;i++) printf("%d ",Next[i]);
}
费马小定理求逆元模板
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,p;
int fastpow(int a,int k,int p){//快速幂
int ans=1;
while(k){
if(k&1) ans=1ll*ans*a%p;
a=1ll*a*a%p;
k>>=1;
}
return ans;
}
int fmny(int x,int p){//费马小定理求逆元,p与x互质
return fastpow(x,p-2,p);
}
int main(){
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++)printf("%d\n",fmny(i,p)%p);
}
递推求逆元模板
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,p;
int a[3000100];
int main(){
scanf("%d%d",&n,&p);
a[1]=1;
for(int i=2;i<=n;i++){
a[i]=(-1ll*(p/i)*a[p%i]%p+p)%p;
printf("%d\n",a[i-1]);
}
printf("%d",(a[n]%p+p)%p);
}
矩阵快速幂模板
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
#define p 1000000007
using namespace std;
int n,k,t;
struct st{
int a[5][5];
inline st operator *(const st &b)const{
st ans;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
ans.a[i][j]=0;
for(int k=0;k<3;k++)
ans.a[i][j]=(1ll*ans.a[i][j]+1ll*a[i][k]*b.a[k][j]%p)%p;
}
return ans;
}
}q;
st fastpow(st a,int k){
st ans=a;k--;
while(k){
if(k&1) ans=ans*a;
a=a*a;
k>>=1;
}
return ans;
}
int main(){
scanf("%d",&t);
q.a[0][0]=1;q.a[0][1]=1;q.a[0][2]=0;q.a[1][0]=0;q.a[1][1]=0;
q.a[1][2]=1;q.a[2][0]=1;q.a[2][1]=0;q.a[2][2]=0;
while(t--){
scanf("%d",&n);
if(n==1||n==2||n==3) {
printf("1\n");
continue;
}
st ans=fastpow(q,n-3);
printf("%d\n",(1ll*ans.a[0][0]+1ll*ans.a[1][0]+1ll*ans.a[2][0])%1000000007);
}
}
卢卡斯定理模板
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<algorithm>
int n,m,p,t,jc[110000];
using namespace std;
int fastpow(int a,int k,int p){//快速幂
int ans=1;
while(k){
if(k&1) ans=1ll*ans*a%p;
a=1ll*a*a%p;
k>>=1;
}
return ans;
}
int c(int n,int m,int p){
if(n<m) return 0;
return 1ll*jc[n]*fastpow(jc[m],p-2,p)%p*fastpow(jc[n-m],p-2,p)%p;
}
int lucas(int n,int m,int p){
return m==0?1:1ll*c(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&p);
jc[0]=1;
for(int i=1;i<=p;i++) jc[i]=1ll*jc[i-1]*i%p;
printf("%d\n",lucas(n+m,m,p)%p);
}
}