一锅大杂烩-------板子合集

数学篇

欧拉筛

#include <cstdio>
using namespace std;
int n,i,j,sc[100005],tot;
bool ss[100005];
int main()
{
    scanf("%d",&n);
    for (i=2;i<=n;i++)
    {
        if (!ss[i])
        {
            ss[i]=true;
            sc[++tot]=i;
        }
        for (j=1;j<=tot&&i*sc[j]<=n;j++)
        {
            ss[i*sc[j]]=true;
            if (i%sc[j]==0) break;
        }
    }
    for (i=1;i<=tot;i++)
      printf("%d ",sc[i]);
}

phi

#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
    int n,i;
    scanf("%d",&n);
    int ans=1;
    for (i=2;i*i<=n;i++)
      if (n%i==0)
      {
        ans*=i-1;n/=i;
        while (n%i==0) n/=i,ans*=i;
      }
    if (n>1) ans*=n-1;
    printf("%d",ans);
}

线性求phi

#include <cstdio>
using namespace std;
int phi[10005];
int main()
{
    int n,i,j;
    scanf("%d",&n);
    phi[1]=1;
    for (i=2;i<=n;i++)
      if (!phi[i])
      {
        for (int j=i;j<=n;j+=i)
        {
            if (!phi[j]) phi[j]=j;
            phi[j]=phi[j]/i*(i-1);
        }
      }
    for (i=1;i<=n;i++)
      printf("%d ",phi[i]);
}

exgcd

#include <cstdio>
using namespace std;
int a,b,x,y,c;
int gcd(int a,int b)
{
    if (b) return gcd(b,a%b);
    else return a;
}
void exgcd(int a,int b,int &x,int &y)
{
    if (!b) {x=1;y=0;}
    else {exgcd(b,a%b,y,x); y-=x*(a/b);}
}
int main()
{
    scanf("%d%d%d",&a,&b,&c);
    exgcd(a,b,x,y);
    int g=gcd(a,b);
    if (c%g==0) 
      printf("%d %d",x*c/g,y*c/g);
}

逆元

Lucas

#include <cstdio>
#define LL long long
using namespace std;
const int N=1e5;
int n,m,p;LL mul[N+5],inv[N+5];
void init()
{
    int i;
    mul[0]=1;
    for (i=1;i<=p;i++)
      mul[i]=mul[i-1]*i%p;
    inv[0]=1; inv[1]=1;
    for (i=2;i<=p;i++)
      inv[i]=(p-(p/i))*inv[p%i]%p;
    for (i=2;i<=p;i++)
      inv[i]=inv[i]*inv[i-1]%p;
}
LL C(int n,int m)
{
    if (n>m) return 0;
    return mul[m]*inv[n]%p*inv[m-n]%p;
}
LL Lucas(int n,int m)
{
    if (n>m) return 0;
    LL ans=1;
    for (;n;n/=p,m/=p) 
      ans=ans*C(n%p,m%p)%p;
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d%d",&n,&m,&p);
        init();
        printf("%lld\n",Lucas(m,m+n)%p);
    }
}

矩阵快速幂

#include <cstdio>  
#include <cstring>  
#define LL long long  
using namespace std;  
const int Mod=1e9+7;  
struct hh{LL sq[105][105];void cl(){memset(sq,0,sizeof(sq));}}ans;  
int n;  
hh work(hh a,hh b)  
{  
    int i,j,k;  
    hh c;c.cl();  
    for (i=1;i<=n;i++)  
      for (j=1;j<=n;j++)  
        for (k=1;k<=n;k++)  
          c.sq[i][j]=(a.sq[i][k]*b.sq[k][j]%Mod+c.sq[i][j])%Mod;  
    return c;  
}  
hh ksm(LL k)  
{  
    hh a;  
    a=ans;  
    for (;k;k>>=1,a=work(a,a))   
      if (k&1) ans=work(ans,a);  
    return ans;  
}  
int main()  
{  
    int i,j;LL k;  
    scanf("%d%lld",&n,&k);  
    for (i=1;i<=n;i++)  
      for (j=1;j<=n;j++)  
      {  
        int a;  
        scanf("%d",&a);  
        ans.sq[i][j]=a;  
      }  
    ans=ksm(k-1);  
    for (i=1;i<=n;i++)  
    {  
        for (j=1;j<=n;j++)  
          printf("%lld ",ans.sq[i][j]);  
        printf("\n");  
    }  
}  

图论篇

st表

#include <cmath>
#include <cstdio>
#include <iostream>
#define sz 19
using namespace std;
const int N=100005;
int maxx[N][sz],n,m,i;
void init()
{
    for (int j=1;j<sz;j++)
      for (int i=1;i<=n;i++)
        if (i+(1<<j)-1<=n)
          maxx[i][j]=max(maxx[i][j-1],maxx[i+(1<<j-1)][j-1]);
        else break;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++) scanf("%d",&maxx[i][0]);
    init();
    while (m--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        int k=log2(r-l+1);
        printf("%d\n",max(maxx[l][k],maxx[r-(1<<k)+1][k]));
    }
}

负环

#include <cstdio>
#include <queue>
#include <iostream>
#include <cstring>
#define N 200000
using namespace std;
int tot,nxt[N*2],point[N],v[N*2],c[N*2],tim[N],dis[N],n;
bool vis[N],fff;
void addline(int x,int y,int z){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z;}
void spfa(int now)
{
    vis[now]=1;
    for (int i=point[now];i;i=nxt[i])
      if (dis[v[i]]>dis[now]+c[i] && !fff)
      {
        dis[v[i]]=dis[now]+c[i];
        if (vis[v[i]]) fff=1;
        spfa(v[i]);
      }
    vis[now]=0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        int m,i;fff=0;tot=0;memset(point,0,sizeof(point));
        scanf("%d%d",&n,&m);
        for (i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            addline(x,y,z);
            if (z>=0) addline(y,x,z);
        }
        memset(dis,0,sizeof(dis));//判负环的时候设成0更好
        memset(vis,0,sizeof(vis));
        for (i=1;i<=n;i++){spfa(i);if (fff) break;}
        if (fff) printf("YE5\n");else printf("N0\n");
    }
}

二分图匹配

#include <cstdio>
#define N 499500+5
using namespace std;
int tot,nxt[N*2],point[N],v[N*2],belong[N],vis[N];
void addline(int x,int y)
{
    ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
}
bool find(int x,int k)
{
    for (int i=point[x];i;i=nxt[i])
      if (vis[v[i]]!=k)
      {
        vis[v[i]]=k;
        if (!belong[v[i]] || find(belong[v[i]],k))
        {
            belong[v[i]]=x;
            return true;
          }
       } 
    return false;
}
int main()
{
    int n,m,e,i,x,y,ans=0;
    scanf("%d%d%d",&n,&m,&e);
    for (i=1;i<=e;i++)
    {
        scanf("%d%d",&x,&y);
        if (x>n || y>m) continue;
        y+=n;addline(x,y);
    }
    for (i=1;i<=n;i++)
      if (find(i,i)) ans++;
    printf("%d",ans);
}

堆dij

#include <cstdio>  
#include <cstring>  
#include <queue>  
#define M 500005  
#define N 10005  
using namespace std;  
struct qnode  
{  
    int node,dis;  
    bool operator <(const qnode a) const {return dis>a.dis;}  
};  
priority_queue<qnode>q;  
int tot,nxt[M],point[M],v[M],cc[M],dis[N];  
bool vis[N];  
void addline(int x,int y,int cap)  
{  
    ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; cc[tot]=cap;  
}  
int main()  
{  
    int n,m,s,i;  
    scanf("%d%d%d",&n,&m,&s);  
    for (i=1;i<=m;i++)  
    {  
        int a,b,c;  
        scanf("%d%d%d",&a,&b,&c);  
        addline(a,b,c);  
    }  
    memset(vis,0,sizeof(vis));  
    memset(dis,0x7f,sizeof(dis));  
    dis[s]=0;  
    q.push((qnode){s,0});  
    while (!q.empty())  
    {  
        qnode noww=q.top(); q.pop();  
        int now=noww.node;  
        if (vis[now]) continue;  
        vis[now]=true;  
        for (i=point[now];i;i=nxt[i])  
          if (dis[v[i]]>dis[now]+cc[i])  
          {  
            dis[v[i]]=dis[now]+cc[i];  
            q.push((qnode){v[i],dis[v[i]]});  
          }  
    }  
    for (i=1;i<=n;i++)  
      if (dis[i]==2139062143) printf("2147483647 ");  
      else printf("%d ",dis[i]);  
}  

手写堆

#include <cstdio>
#include <iostream>
using namespace std;
int q[1000005],tot=0;
void push(int x)
{
    q[++tot]=x;
    int fa=tot>>1,now=tot;
    while (fa&&q[fa]>q[now])
    {
        swap(q[fa],q[now]);
        now=fa; fa>>=1;
    }
}
void del()
{
    q[1]=q[tot--];
    int now=1,l=now<<1,r=now<<1|1,better=l;
    if (r<=tot && q[r]<q[l]) better=r; 
    while (better<=tot && q[now]>q[better])
    {
        swap(q[now],q[better]);
        now=better; l=now<<1; r=now<<1|1;
        better=l;
        if (r<=tot && q[r]<q[l]) better=r; 
    }
}
int main()
{
    int Q;
    scanf("%d",&Q);
    while (Q--)
    {
        int id,x;scanf("%d",&id);
        if (id==1)
        {
            scanf("%d",&x);
            push(x);
        }
        else if (id==2) printf("%d\n",q[1]);
        else del();
    }
}

树链剖分

#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;
const int N=100005;
int tot,nxt[N*2],point[N],v[N*2];
int h[N],size[N],father[N],son[N],top[N],totw,num[N],out[N],a[N],tree[N*4];
LL ww[N*4],p,delta[N*4];
void addline(int x,int y)
{
    ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
    ++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;
}
void dfs_1(int now,int dep,int fa)
{
    h[now]=dep;father[now]=fa;int maxx=0;
    for (int i=point[now];i;i=nxt[i])
      if (v[i]!=fa)
      {
        dfs_1(v[i],dep+1,now);
        size[now]+=size[v[i]];
        if (maxx<size[v[i]]){maxx=size[v[i]]; son[now]=v[i];}
      }
    size[now]++;
}
void dfs_2(int now,int fa)
{
    if (son[fa]==now) top[now]=top[fa];
    else top[now]=now;
    num[now]=++totw;
    if (son[now])
    {
        dfs_2(son[now],now);
        for (int i=point[now];i;i=nxt[i])
          if (v[i]!=fa && v[i]!=son[now])
            dfs_2(v[i],now);
    }
    out[now]=totw;
}
void updata(int now){ww[now]=ww[now<<1]+ww[now<<1|1];}
void build(int now,int l,int r)
{
    if (l==r)
    {
        ww[now]=a[tree[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    updata(now);
}
void pushdown(int now,int l,int r,int mid)
{
    if (delta[now])
    {
        ww[now<<1]=(ww[now<<1]+(LL)(mid-l+1)*delta[now])%p;
        ww[now<<1|1]=(ww[now<<1|1]+(LL)(r-mid)*delta[now]%p)%p;
        delta[now<<1]+=delta[now];
        delta[now<<1|1]+=delta[now];
        delta[now]=0;
    }
}
void change(int now,int l,int r,int lrange,int rrange,int k)
{
    if(lrange<=l && rrange>=r) 
    {
        delta[now]+=k;
        ww[now]=(r-l+1)*k%p+ww[now];
        ww[now]%=p;
        return;
    }
    int mid=(l+r)>>1;pushdown(now,l,r,mid);
    if (lrange<=mid) change(now<<1,l,mid,lrange,rrange,k);
    if (rrange>mid) change(now<<1|1,mid+1,r,lrange,rrange,k);
    updata(now);
}
LL qurry(int now,int l,int r,int lrange,int rrange)
{
    int mid=(l+r)>>1;LL ans=0;pushdown(now,l,r,mid);
    if(lrange<=l && rrange>=r) return ww[now];
    if (lrange<=mid) ans=(ans+qurry(now<<1,l,mid,lrange,rrange))%p;
    if (rrange>mid) ans=(ans+qurry(now<<1|1,mid+1,r,lrange,rrange))%p;
    ans%=p; return ans;
}
int main()
{
    int n,m,r,i;
    scanf("%d%d%d%lld",&n,&m,&r,&p);
    for (i=1;i<=n;i++) scanf("%d",&a[i]);
    for (i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        addline(x,y);
    }
    dfs_1(r,1,0); dfs_2(r,0);
    for (i=1;i<=n;i++) tree[num[i]]=i;
    build(1,1,n);
    while (m--)
    {
        int id,x,y,z;
        scanf("%d",&id);
        if (id==1)
        {
            scanf("%d%d%d",&x,&y,&z);
            int f1=top[x],f2=top[y];
            while (f1!=f2)
            {
                if (h[f1]<h[f2]){swap(f1,f2); swap(x,y);}
                change(1,1,n,num[f1],num[x],z);
                x=father[f1]; f1=top[x];
            }
            if (num[x]>num[y]) swap(x,y);
            change(1,1,n,num[x],num[y],z);
        }
        else if (id==2)
        {
            scanf("%d%d",&x,&y);
            int f1=top[x],f2=top[y];LL ans=0;
            while (f1!=f2)
            {
                if (h[f1]<h[f2]){swap(f1,f2); swap(x,y);}
                ans+=qurry(1,1,n,num[f1],num[x]); ans%=p;
                x=father[f1]; f1=top[x];
            }
            if (num[x]>num[y]) swap(x,y);
            ans+=qurry(1,1,n,num[x],num[y]); ans%=p;
            printf("%lld\n",ans);
        }
        else if (id==3)
        {
            scanf("%d%d",&x,&z);
            change(1,1,n,num[x],out[x],z);
        }
        else
        {
            scanf("%d",&x);
            printf("%lld\n",qurry(1,1,n,num[x],out[x])%p);
        }
    }
}

字符篇

KMP

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int t[1000005],l1,l2,i;
char s1[1000005],s2[1000005];
void kmp()//失配函数都是被匹配串的。 
{
    t[0]=-1;
    for (int i=0;i<l2;i++)
    {
        int j=t[i];
        while (j!=-1 && s2[i]!=s2[j]) j=t[j];
        t[i+1]=++j;
    }
}
int main()
{
    scanf("%s%s",s1,s2);
    l1=strlen(s1); l2=strlen(s2);
    kmp();int j=0;
    for (i=0;i<l1;i++)
    {
        while (s1[i]!=s2[j] && j!=-1) j=t[j];
        j++;
        if (j==l2)
        {
            printf("%d\n",i-l2+2);
            j=t[j];
        } 
    }
    for (i=1;i<=l2;i++) printf("%d ",t[i]); 
}

AC自动机

#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=1e6;
int ch[N+5][30],is_end[N+5],tot,fail[N+5];
char ss[N+5],st[N+5];bool vis[N+5];
void trie()
{
    int now=0,l=strlen(ss);
    for (int i=0;i<l;i++)
    {
        int x=ss[i]-'a';
        if (!ch[now][x]) ch[now][x]=++tot;
        now=ch[now][x];
    }
    is_end[now]++;
}
void sp()
{
    queue<int>q;
    int now=0;
    for (int i=0;i<26;i++)
      if (ch[now][i]) q.push(ch[now][i]);
    while (!q.empty())
    {
        int now=q.front(); q.pop();
        for (int i=0;i<26;i++)
        {
            if (!ch[now][i])
            {
                ch[now][i]=ch[fail[now]][i];
                continue;
            }
            fail[ch[now][i]]=ch[fail[now]][i];
            q.push(ch[now][i]);
        }
    }
}
void ac()
{
    int now=0,l=strlen(st),ans=0;
    for (int i=0;i<l;i++)
    {
        vis[now]=1;
        int x=st[i]-'a';
        int y=ch[now][x];
        while (y && !vis[y])
        {
            vis[y]=1;
            ans+=is_end[y];
            y=fail[y];
        }
        now=ch[now][x];
    }
    printf("%d",ans);
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--){scanf("%s",ss);trie();}
    sp();
    scanf("%s",st);
    ac();
}

字符串hash

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值