ACM模版
#include<bits/stdc++.h>
#include<iostream>//c++
#include<cmath>//数学公式
#include<cstdlib>//malloc
#include<cstring>
#include<string>
#include<cstdio>//输入输出
#include<algorithm>//快排
#include<queue>//队列
#include<functional>//优先队列
#include<stack>//栈
#include<vector>//容器
#include<map>//地图 if
typedef long long ll;
const int N=30+1e3;
const int inf=1e3;
using namespace std;
int main()
{
int i,j,k,t,ans,n,m,tmp,tt=0;
scanf("%d",&t);
while(t--)
{
int a,b,c;
}
return 0;
}
快速幂
typedef long long ll;
const int mod=1000000+30;
ll pow(int n,int p)
{
ll ans=1;
while(p>0)
{
if(p&1) ans=(ans*n)%mod;
p>>=1;
n=(n*n)%mod;
}
return ans;
}
最大公约数,最小公倍数
int gcd(int x,int y)
{
return x%y?gcd(y,x%y):y;
}
int lcm(int x,int y)
{
return x*y/gcd(x,y);
}
排列组合(1—n的全排列)
int a[100],n=3,i;
for(i=0;i<n;i++) a[i]=i+1;
sort(a,a+n);//先保证从小到大排列
do{
for(i=0;i<n;i++) cout<<a[i];
cout<<endl;
}while(next_permutation(a,a+n));
素数判断
bool prime(int a)//默认1是
{
if (a==2||a== 3) return 1;
if (a%6!=1 &&a%6!= 5) return 0;
for(int i=5;i*i<=a;i+= 6)
if (a% i == 0 ||a % (i+2) == 0)
return 0;
return 1;
}
素数打表:
void prime()
{
int i,j,in[6]={0,4,0,0,0,2};
for(i=5;i*i<=N;i+=in[i%6])
for(j=i;i*j<=N;j+=in[j%6])
a[i*j]=1;
}
if(i==2||i==3||( (i%6==1||i%6==5)&&a[i]==0 ) )
字符串:
memset();
memccpy();
strcmp();
strcpy();
strrev(s2);
swap();
1e
a=97; z=122; A=65; Z=90;
sqrt(); abs();
min() max() 可以处理double类型的数字
'\\'//特殊字符的处理
double ans=6.66666666; printf("%d\n",(int)ans*1000);//避免进位
double ans=6.66666666; printf("%.3lf\n",1.0*(int)(ans*1000)/1000);//避免进位
去重
int w[N];
int qu(int n)
{
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
if(w[i]>w[j]) swap(w[i],w[j]);
else if(w[i]==w[j]) swap(w[j],w[n-1]),n--,j--;
return n;
}
并查集(1)
int pre[N]={0};
void un(int a,int b,int n)
{
int c=pre[a];
for(int i=1;i<=n;i++)
if(c==pre[i]) pre[i]=pre[b];
}
for(i=1;i<=N;i++) pre[i]=i;
并查集(2)
int pre[N]={0};
int finds(int x)
{
if(pre[x]!=x) pre[x]=finds(pre[x]);
return pre[x];
}
void un(int x,int y)
{
x=finds(x);
y=finds(y);
if(x!=y) pre[x]=y;
}
for(i=1;i<=N;i++) pre[i]=i;
a进制转十
制
const int p=16;//p代表 a进制
string s;
int a()
{
int n=0,fal=1;
for(int i=0;i<s.size();i++)
{
if(s[i]=='-') fal=-1;
else if(s[i]>'9') n=n*p+s[i]-55;//字母大写 -55
else n=n*p+s[i]-'0';
}
return n*fal;
}
十进制转b进制
const int p=16;//p代表 b进制
stack<int> s;
void swit(int n)
{
int tmp;
if(n==0) s.push(0);
while (n!=0)
{
tmp=n%p;
n=n/p;
s.push(tmp);
}
while(!s.empty())
{
if(s.top()>=10) cout<<(char)(s.top()+55);
else cout<<s.top();
s.pop();
}
}
三角函数
const double pi=3.1415926535;
double san()
{
double a,n,b,l;
b=a/180*pi;//变为弧度为b
b=a/pi*180;//变为角度为b
//asin(b),sin(b),acos(b),cos(b),atan(b),tan(b) b为弧度
return l*l*n/4/tan(pi/n);//边长为lr的 正n边形面积
}
扩展欧几里德
ll gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0){
x = 1;
y = 0;
return a;
}
ll g=gcd(b,a%b,x,y);
ll tmp=x;
x=y;
y=tmp-(a/b)*y;
return g;
}
ll oula(ll a,ll b,ll x,ll y,ll n)//ax+by=n
{
ll c=gcd(a,b,x,y);
if(n%c) {cout<<"Impossible"<<endl;return 0;}//判断是否有解
n/=c;b/=c;a/=c;
x*=n;
y*=n;//x y 为ax+by=n的解 通解x+=k*b y+=k*a
x%=b;
if(x<0) x+=b;
cout<<x<<endl;
}
结构体优先队列
typedef struct{
int a,b,c;
}G;G g[100];
struct cmp{
bool operator() (G x ,G y)
{
return x.c>y.c;//小到大
}
};
priority_queue<G ,vector<G> ,cmp >q;//结构体优先队列
priority_queue<int> q1;//大到小
priority_queue<int, vector<int>,greater<int> >q2;//小到大
sort
typedef struct{
int a,b,c;
}G;G g[100];
bool cmp(G x,G y)
{
return x.c<y.c;//小到大
}
sort(g,g+10,cmp);
位运算
//八进制 OCT
cout<<oct<<test<<endl;
printf("%o\n",test);
//十六进制 HEX
cout<<hex<<test<<endl;
printf("%x\n",test);
群
bool label[N];
void dfs(int tmp)
{
for(int i=1;i<=n;i++)
if(!label[i]&&i==tmp)
{
label[i]=1;
if(!label[w[i]])
dfs(w[i]);
}
}
int qun()
{
memset(label,0,sizeof(label));
int ans=0;
for(int i=1;i<=n;i++)
if(!label[i]) label[i]=1,dfs(w[i]),ans++;
return ans;
}
树状数组
void add(int k,int num)
{
while(k<=n)
{
tree[k]+=num;
k+=k&-k;
}
}
int read(int k)//1~k的区间和
{
int sum=0;
while(k)
{
sum+=tree[k];
k-=k&-k;
}
return sum;
}
#define lson L,R,l,m,rt<< 1
#define rson L,R,m+1,r,rt<<1|1
#define son 1,n,1
const int N=200000;
int sum[N<<2];
void update(int L,int R,int l,int r,int rt,int val)//更新 区间(l r) l r n val
{
if(L<=l&&r<= R) {sum[rt]+=val;return;}
int m=(l+r)>>1;
if(L<=m) update(lson,val);
if(R> m) update(rson,val);
//sum[rt]+=val;
}
int query(int L,int R,int l,int r,int rt)//查询 区间(l r) l r n
{
if(L<=l&&r<= R) return sum[rt];
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret+=query(lson);
if(R>m) ret+=query(rson);
return ret+sum[rt];
}
LIS
</pre><pre name="code" class="cpp">int a[N],dp[N];//可以改为char
int n;//1-n
int bin(int size,int k)
{
int l=1,r=size;
while(l<=r)
{
int mid =(l+r)/2;
if(k>dp[mid]) l = mid+1;
else r = mid-1;
}
return l;
}
int lis()
{
int i,j,cnt=0,k;
for(i=1;i<=n; i++)
{
if(cnt==0||a[i]>dp[cnt]) dp[++cnt] = a[i];
else
{
k = bin(cnt,a[i]);
dp[k]=a[i];
}
}
return cnt;
}
int lis(int n)
{
memset(dp,0,sizeof(dp));
int ans=0;
for (int i=0;i<n;i++)
{
for (int j=0;j<i;j++)
if(b[j]<=b[i]) dp[i]=max(dp[i],dp[j]+1);
ans=max(ans,dp[i]);
}
return ans;
}
LCS
int lcs(int n,int m)
{
memset(dp,0,sizeof(dp));
for(int i=0;i<m;i++)
for(int j=0,ans=0;j<n;j++)
{
int tmp=dp[j];
if(s1[i]==s2[j]) dp[j]=ans+1;
else dp[j]=max(dp[j],dp[j-1]);
ans=tmp;
}
}
二分图(最大匹配)
int mapa[N][N],visited[N],father[N];
int n,m,e;//n行m列
int dfs(int i)
{
for(int j=1;j<=m;j++)
if (mapa[i][j] && !visited[j])//mapa 1连通 0不连通
{
visited[j] = 1;
if (father[j]==-1||dfs(father[j]))
{
father[j] =i;
return 1;
}
}
return 0;
}
void solve()
{
int ans = 0;
memset(father,-1,sizeof(father));
for (int i = 1; i <= n; i++)
{
memset(visited,0,sizeof(visited));
if (dfs(i)) ans++;
}
printf("Case %d: %d\n",tem++,ans);
}
字典树
struct node{
int num;
node *next[30];
node(){
memset(next,0,sizeof(next));
num=0;
}
};
node *root=new node;
node *p;
char dir[32],s[32];
void Insert(){
p=root;
for(int i=0;s[i];i++)
{
int x=s[i]-'a';
if(p->next[x]==NULL) p->next[x]=new node;
p=p->next[x];
p->num++;
}
}
int Search(){
p=root;
for(int i=0;s[i];i++){
int x=s[i]-'a';
if(p->next[x]==NULL)
return 0;
p=p->next[x];
}
return p->num;
}
void Delete(int cnt){
p=root;
for(int i=0;s[i];i++)
{
int x=s[i]-'a';
p=p->next[x];
p->num-=cnt;
}
for(int i=0;i<30;i++) p->next[i]=0;
}
int cnt=Search();
if(cnt) Delete(cnt);
KMP
int n,m;
int next[10011];
int a[1000111];
int b[10011];
void getnext()
{
int i=0,k=-1;
next[0]=-1;
while(i<m)
{
if(k==-1||b[i]==b[k]) next[++i]=++k;
else k=next[k];
}
}
int kmp()
{
int i,j=0;
for(i=0;i<n;)
if(a[i]==b[j])
{
if(j==m-1) return i-j+1;
i++;j++;
}
else
{
j=next[j];
if(j==-1) {i++;j=0;}
}
return -1;
}
找循环节