zoukankan      html  css  js  c++  java
  • 各种模板

    最短路

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    const int maxm=2e6+5;
    const int inf=0x7fffffff;
    int h[maxn],vis[maxn],dis[maxn];
    int tot,n,m,s;
    struct edge
    {
        int u;//next
        int v;//to
        int w;//weight
    }e[maxm];
    struct node
    {
        int now;
        int w;
        bool operator<(const node&a)const
        {
            return w>a.w;
        }
    };
    inline void add(int u,int v,int w)
    {
        tot++;
        e[tot].v=v;
        e[tot].w=w;
        e[tot].u=h[u];
        h[u]=tot;
    }
    inline void dijkstra()
    {
        for(int i=1;i<=n;++i)
        {
            dis[i]=inf;
        }
        dis[s]=0;
        priority_queue<node> que;
        que.push((node){s,0});
        while(!que.empty())
        {
            node x=que.top();
            que.pop();
            int u=x.now;
            if(vis[u])continue;
            vis[u]=1;
            for(int i=h[u];i;i=e[i].u)
            {
                int v=e[i].v;
                if(dis[v]>dis[u]+e[i].w)
                {
                    dis[v]=dis[u]+e[i].w;
                    que.push((node){v,dis[v]});
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&s);
        for(int i=1;i<=m;++i)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        dijkstra();
        for(int i=1;i<=n;++i)
        {
            printf("%d ",dis[i]);
        }
        return 0;
    }
    dijkstra

     最小生成树

    #include <bits/stdc++.h>
    using namespace std;
    const int inf=0x7fffffff;
    const int maxn=5e3+5;
    const int maxm=2e5+5;
    int h[maxn],dis[maxn],vis[maxn];
    int n,m,tot,cnt,ans,now=1;
    struct edge
    {
        int u;
        int v;
        int w;
    }e[maxm<<1];
    inline void add(int u,int v,int w)
    {
        tot++;
        e[tot].v=v;
        e[tot].w=w;
        e[tot].u=h[u];
        h[u]=tot;
    }
    inline int prim()
    {
        for(int i=2;i<=n;++i)
        {
            dis[i]=inf;
        }
        for(int i=h[1];i;i=e[i].u)
        {
            dis[e[i].v]=min(dis[e[i].v],e[i].w);
        }
        while(++cnt<n)
        {
            int mmin=inf;
            vis[now]=1;
            for(int i=1;i<=n;++i)
            {
                if(!vis[i]&&mmin>dis[i])
                {
                    mmin=dis[i];
                    now=i;
                }
            }
            ans+=mmin;
            for(int i=h[now];i;i=e[i].u)
            {
                int v=e[i].v;
                if(!vis[v]&&dis[v]>e[i].w)
                {
                    dis[v]=e[i].w;
                }
            }
        }
        return ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;++i)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        printf("%d\n",prim());
        return 0;
    }
    prim
    #include <bits/stdc++.h>
    using namespace std;
    const int inf=0x7fffffff;
    const int maxn=5e3+5;
    const int maxm=2e5+5;
    int f[maxn];
    int n,m,eu,ev,cnt,ans;
    struct edge
    {
        int u;
        int v;
        int w;
    }e[maxm];
    inline bool cmp(const edge&a,const edge&b)
    {
        return a.w<b.w;
    }
    inline int find_(int x)
    {
        return f[x]==x?x:f[x]=find_(f[x]);
    }
    inline void kruskal()
    {
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=m;++i)
        {
            eu=find_(e[i].u);
            ev=find_(e[i].v);
            if(eu==ev)continue;
            ans+=e[i].w;
            f[ev]=eu;
            if(++cnt==n-1)break;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)f[i]=i;
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        }
        kruskal();
        printf("%d\n",ans);
        return 0;
    }
    kruskal

     字符串

    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e6+5;
    int kmp[N];
    char a[N],b[N];
    int main()
    {
        scanf("%s%s",a+1,b+1);
        int alen=strlen(a+1);
        int blen=strlen(b+1);
        for(int i=2,j=0;i<=blen;++i)
        {
            while(j&&b[i]!=b[j+1])j=kmp[j];
            if(b[i]==b[j+1])j++;
            kmp[i]=j;
        }
        for(int i=1,j=0;i<=alen;++i)
        {
            while(j&&a[i]!=b[j+1])j=kmp[j];
            if(a[i]==b[j+1])j++;
            if(j==blen)
            {
                printf("%d\n",i-blen+1);
                j=kmp[j];
            }
        }
        for(int i=1;i<blen;++i)
        {
            printf("%d ",kmp[i]);
        }
        printf("%d\n",kmp[blen]);
        return 0;
    }
    kmp
    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    int tree[N][30];
    bool flag[N];
    int tot;
    inline bool insert_(string s)
    {
        int len=s.size();
        int rt=0;
        int id;
        for(int i=0;i<len;++i)
        {
            if(s[i]>='a'&&s[i]<='z')id=s[i]-'a';
            if(tree[rt][id]==0)tree[rt][id]=++tot;
            rt=tree[rt][id];
        }
        int mark=flag[rt];
        flag[rt]=1;
        return !mark;
    }
    inline bool find_(char *s)
    {
        int len=strlen(s);
        int rt=0;
        int id;
        for(int i=0;i<len;++i)
        {
            if(s[i]>='a'&&s[i]<='z')id=s[i]-'a';
            if(tree[rt][id]==0)return 0;
            rt=tree[rt][id];
        }
        return flag[rt];
    }
    int main()
    {
        ios::sync_with_stdio(false);
        while(1)
        {
            tot=0;
            memset(tree,0,sizeof(tree));
            memset(flag,0,sizeof(flag));
            int ans=0;
            string a;
            getline(cin,a);
            stringstream ss(a);
            int i=0;
            while(ss>>a)
            {
                if(a[0]=='#'&&i==0)return 0;
                ans+=insert_(a);
                ++i;
            }
            printf("%d\n",ans);
        }
    }
    trie
    #include <bits/stdc++.h>
    using namespace std;
    const int N=61100000;
    char a[N],s[N<<1];
    int n,hw[N],mmax=1;
    inline void change()
    {
        s[0]=s[1]='#';
        for(int i=0;i<n;++i)
        {
            s[i*2+2]=a[i];
            s[i*2+3]='#';
        }
        n=n*2+2;
        s[n]=0;
    }
    void manacher()
    {
        int maxright=0,mid;
        for(int i=1;i<n;i++)
        {
            if(i<maxright)hw[i]=min(hw[(mid<<1)-i],maxright-i);
            else hw[i]=1;
            for(;s[i+hw[i]]==s[i-hw[i]];++hw[i]);
            if(hw[i]+i>maxright)
            {
                maxright=hw[i]+i;
                mid=i;
            }
            mmax=max(mmax,hw[i]);
        }
    }
    int main()
    {
        scanf("%s",a);
        n=strlen(a);
        change();
        manacher();
        cout<<mmax-1;
        return 0;
    }
    manacher
    #include <bits/stdc++.h>
    #define maxn 1000005
    using namespace std;
    int tree[maxn][26];
    int val[maxn];
    int fail[maxn];
    int cnt=0;
    inline void build(char *s)
    {
        int len=strlen(s);
        int now=0;
        for(int i=0;i<len;++i)
        {
            int v=s[i]-'a';
            if(tree[now][v]==0)tree[now][v]=++cnt;
            now=tree[now][v];
        }
        val[now]++;
    }
    inline void get_fail()
    {
        queue<int>q;
        for(int i=0;i<26;++i)
        {
            if(tree[0][i])
            {
                fail[tree[0][i]]=0;
                q.push(tree[0][i]);
            }
        }
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=0;i<26;++i)
            {
                if(tree[u][i])
                {
                    fail[tree[u][i]]=tree[fail[u]][i];
                    q.push(tree[u][i]);
                }
                else tree[u][i]=tree[fail[u]][i];
            }
        }
    }
    inline int ac_query(char *s)
    {
        int len=strlen(s);
        int now=0,ans=0;
        for(int i=0;i<len;++i)
        {
            now=tree[now][s[i]-'a'];
            for(int k=now;k&&val[k]!=-1;k=fail[k])
            {
                ans+=val[k];
                //val[k]=-1;
            }
        }
        return ans;
    }
    struct sss
    {
        char s[10001];
    }ss[100003];
    char str[maxn];
    int main()
    {
        int t,n;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            memset(val,0,sizeof(val));
            memset(tree,0,sizeof(tree));
            memset(fail,0,sizeof(fail));
            for(int i=1;i<=n;++i)
            {
                scanf("%s",ss[i].s);
            }
            for(int i=1;i<=m;++i)
            {
                scanf("%s",str);
                build(str);
            }
            get_fail();
            for(int i=1;i<=n;++i)
            {
                printf("%d\n",ac_query(ss[i].s));
            }
        }
        return 0;
    }
    /*
    5
    she
    he
    say
    shr
    her
    yasherhs
    */
    ac自动机

    ST表

    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    using namespace std;
    int st[50][100010];
    inline int Max(int a,int b)
    {
        return a>b?a:b;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;++i)
        {
            cin>>st[0][i];
        }
        int t=log2(n);
        for(int i=1;i<=t;++i)
        {
            for(int j=1;j+(1<<i)-1<=n;++j)
            {
                st[i][j]=Max(st[i-1][j],st[i-1][j+(1<<(i-1))]);
            }
        }
        while(m--)
        {
            int l,r;
            cin>>l>>r;
            int t=log2(r-l+1);
            cout<<Max(st[t][l],st[t][r-(1<<t)+1])<<endl;
        }
        return 0;
    }
    st表

    矩阵快速幂

    #include <bits/stdc++.h>
    using namespace std;
    const int MOD=1e9+7;
    const int maxn=110;
    typedef long long ll;
    ll n,kk;
    struct mat
    {
        ll m[maxn][maxn];
    }c,d,e,o;
    inline mat mul(const mat &a,const mat &b)
    {
        mat ret=o;
        for(int i=1;i<=3;++i)
        {
            for(int j=1;j<=3;++j)
            {
                for(int k=1;k<=3;++k)
                {
                   ret.m[i][j]=(ret.m[i][j]+a.m[i][k]*b.m[k][j]%MOD)%MOD;
                }
            }
        }
        return ret;
    }
    inline mat qpow(mat x,ll y)
    {
        mat ans=e;
        while(y)
        {
            if(y&1)ans=mul(ans,x);
            x=mul(x,x);
            y>>=1;
        }
        return ans;
    }
    int main()
    {
        scanf("%lld",&n);
        for(int i=1;i<=3;++i)
        {
            for(int j=1;j<=3;++j)
            {
                o.m[i][j]=0;
            }
            e.m[i][i]=1;
        }
        d=o;
        d.m[1][1]=1;
        d.m[1][2]=1;
        d.m[2][3]=1;
        d.m[3][1]=1;
        c=o;
        c.m[1][1]=1;
        c.m[1][2]=1;
        c.m[1][3]=1;
        for(int i=1;i<=n;++i)
        {
            scanf("%lld",&kk);
            if(kk<3)
            {
                printf("1\n");
                continue;
            }
            mat ans=qpow(d,kk-3);
            ans=mul(c,ans);
            printf("%lld\n",ans.m[1][1]);
        }
        return 0;
    }
    矩阵快速幂
    #include <cstdio>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    const int n=1e6+5;
    int vis[n],phi[n],p[n],cnt;
    ll ans[n];
    ll oula(ll n)
    {
        ll res=n;
        for(ll i=2;i*i<=n;++i)
        {
            if(n%i==0)res=res/i*(i-1);
            while(n%i==0)n/=i;
        }
        if(n>1)res=res/n*(n-1);
        return res;
    }
    void oulashai()
    {
        phi[1]=1;
        for(int i=2;i<=n;++i)
        {
            if(vis[i]==0)//i为素数
            {
                p[++cnt]=i;//将i加入素数数组p中
                phi[i]=i-1;//因为i是素数,由特性得知
            }
            for(int j=1;j<=cnt&&i*p[j]<=n;++j)  //用当前已得到的素数数组p筛,筛去p[j]*i
            {
                vis[i*p[j]]=1;//可以确定i*p[j]不是素数
                if(i%p[j]==0) //看p[j]是否是i的约数,因为素数p[j],等于判断i和p[j]是否互质
                {
                    phi[i*p[j]]=phi[i]*p[j]; //特性2
                    break;
                }
                else phi[i*p[j]]=phi[i]*phi[p[j]];//(p[j]-1); //互质,特性3其,p[j]-1就是phi[p[j]]
            }
        }
    }
    //m[i]标记i是否为素数,0为素数,1不为素数;p是存放素数的数组;nump是当前素数个数;phi[i]为欧拉函数
    int main()
    {
        oulashai();
        int t;
        for(int i=1;i<=n;++i)
        {
            ans[i]=ans[i-1]+phi[i];
        }
        while(~scanf("%d",&t)&&t)
        {
            cout<<ans[t]-1<<endl;
        }
        return 0;
    }
    欧拉函数

    数论

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n;
    ll f[50];
    ll c[50][50];
    ll ff[40];
    inline void init()
    {
        f[1]=0;
        f[2]=1;
        for(int i=3;i<=35;++i)
        {
            f[i]=(i-1)*(f[i-1]+f[i-2]);
        }
        c[0][0]=1;
        for(int i=1;i<=35;++i)
        {
            for(int j=0;j<=i;++j)
            {
                c[i][j]=c[i-1][j-1]+c[i-1][j];
            }
        }
        ff[0]=ff[1]=1;
        for(int i=2;i<=35;++i)
        {
            for(int j=0;j<i;++j)
            {
                ff[i]+=ff[j]*ff[i-j-1];
            }
        }
    }
    int main()
    {
        init();
        int t;
        int cnt=0;
        while(~scanf("%d",&t))
        {
            if(t==-1)break;
            printf("%d %d %lld\n",++cnt,t,ff[t]*2);
        }
        return 0;
    }
    卡特兰数错排组合数

    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    #define lowbit(i)(i&(-i))
    #define Max(a,b)(((a)>(b))?(a):(b))
    #define Min(a,b)(((a)<(b))?(a):(b))
    using namespace std;
    const int maxn=200010;
    typedef long long ll;
    ll a[maxn];//原数据
    ll c1[maxn];//记录区间增量
    ll c2[maxn];
    ll asum[maxn];//差分原数据
    ll mmax[maxn];
    ll mmin[maxn];
    int n,m;
    inline void add(ll *arr,int x,ll val)//修改节点
    {
        while(x<=n)
        {
            arr[x]+=val;
            x+=lowbit(x);
        }
    }
    inline void qj_add(int l,int r,ll val)//区间修改 运用了差分的思想
    {
        add(c1,l,val);
        add(c1,r+1,-val);
        add(c2,l,val*l);//*1
        add(c2,r+1,-val*(r+1));
    }
    inline ll sum(ll *arr,ll x)
    {
        ll ans=0;
        while(x)
        {
            ans+=arr[x];
            x-=lowbit(x);
        }
        return ans;
    }
    inline ll F(int x)
    {
        return asum[x]+(x+1)*sum(c1,x)-sum(c2,x);
    }
    inline ll query(int l,int r)//区间查询
    {
        return F(r)-F(l-1);
    }
    inline int max_query(int l,int r)
    {
        int ans=a[r];
        while(l!=r)
        {
            r--;
            while(r-l>=lowbit(r))
            {
                ans=Max(ans,mmax[r]);
                r-=lowbit(r);
            }
            ans=Max(ans,a[r]);
        }
        return ans;
    }
    inline int min_query(int l,int r)
    {
        int ans=a[r];
        while(l!=r)
        {
            r--;
            while(r-l>=lowbit(r))
            {
                ans=Min(ans,mmin[r]);
                r-=lowbit(r);
            }
            ans=Min(ans,a[r]);
        }
        return ans;
    }
    inline void update(int x,ll val)
    {
        a[x]=val;
        while(x<=n)
        {
            mmax[x]=a[x];
            mmin[x]=a[x];
            for(int j=1;j<lowbit(x);j<<=1)
            {
                mmax[x]=Max(mmax[x],mmax[x-j]);
                mmin[x]=Min(mmin[x],mmin[x-j]);
            }
            x+=lowbit(x);
        }
    }
    树状数组
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=200005;
    typedef long long ll;
    double sum[maxn<<2];
    double pls[maxn<<2];
    double mul[maxn<<2];
    int n,m;
    inline void pushup(int rt)//往上更新区间和
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    inline void build(int rt,int l,int r)
    {
        if(l==r)
        {
            scanf("%lf",&sum[rt]);
            return;
        }
        mul[rt]=1;
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    inline void pushdown(int rt,int l,int r)
    {
        int mid=(l+r)>>1;
        sum[rt<<1]*=mul[rt];
        mul[rt<<1]*=mul[rt];
        pls[rt<<1]*=mul[rt];
        sum[rt<<1|1]*=mul[rt];
        mul[rt<<1|1]*=mul[rt];
        pls[rt<<1|1]*=mul[rt];
        sum[rt<<1]+=pls[rt]*(mid-l+1);
        pls[rt<<1]+=pls[rt];
        sum[rt<<1|1]+=pls[rt]*(r-mid);
        pls[rt<<1|1]+=pls[rt];
        pls[rt]=0;
        mul[rt]=1;
    }
    inline void add_qj(int rt,int l,int r,int ql,int qr,double k)//区间加
    {
         if(ql<=l&&r<=qr)
         {
            sum[rt]+=k*(r-l+1);
            pls[rt]+=k;
            return;
         }
         pushdown(rt,l,r);
         int mid=(l+r)>>1;
         if(ql<=mid)add_qj(rt<<1,l,mid,ql,qr,k);
         if(qr>mid)add_qj(rt<<1|1,mid+1,r,ql,qr,k);
         pushup(rt);
    }
    inline void mul_qj(int rt,int l,int r,int ql,int qr,double k)//区间乘
    {
        if(ql<=l&&r<=qr)
        {
            sum[rt]*=k;
            mul[rt]*=k;
            pls[rt]*=k;
            return;
        }
        pushdown(rt,l,r);
        int mid=(l+r)>>1;
        if(ql<=mid)mul_qj(rt<<1,l,mid,ql,qr,k);
        if(qr>mid)mul_qj(rt<<1|1,mid+1,r,ql,qr,k);
        pushup(rt);
    }
    double query(int rt,int l,int r,int ql,int qr)//单点查询
    {
       if(ql<=l&&r<=qr)return sum[rt];
       pushdown(rt,l,r);
       int mid=(l+r)>>1;
       double sum1=0,sum2=0;
       if(ql<=mid)sum1+=query(rt<<1,l,mid,ql,qr);
       if(qr>mid)sum2+=query(rt<<1|1,mid+1,r,ql,qr);
       return sum1+sum2;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        build(1,1,n);
        while(m--)
        {
            int opt;
            scanf("%d",&opt);
            if(opt==1)
            {
                int a,b,c,d;
                scanf("%d%d%d%d",&a,&b,&c,&d);
                double l1=b-a+1,l2=d-c+1;
                double s1=query(1,1,n,a,b);
                double s2=query(1,1,n,c,d);
                mul_qj(1,1,n,a,b,(l1-1)/l1);
                mul_qj(1,1,n,c,d,(l2-1)/l2);
                add_qj(1,1,n,a,b,1.0/l1*(s2/l2));
                add_qj(1,1,n,c,d,1.0/l2*(s1/l1));
            }
            else
            {
                int a,b;
                scanf("%d%d",&a,&b);
                printf("%.5f\n",query(1,1,n,a,b));
            }
        }
        return 0;
    }
    新线段树
     背包
    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    #define Max(a,b)(((a)>(b))?(a):(b))
    using namespace std;
    const int maxn=100010;
    const int inf=0x3f3f3f3f;
    int f[maxn],c[maxn],w[maxn];
    inline void completepack(int v,int w,int m)
    {
        for(int j=v;j<=m;++j)
        {
            f[j]=Max(f[j],f[j-v]+w);
        }
    }
    inline void zeroonepack(int v,int w,int m)
    {
        for(int j=m;j>=v;--j)
        {
            f[j]=Max(f[j],f[j-v]+w);
        }
    }
    inline void multipack(int v,int w,int m,int c)
    {
        if(v*c>m)
        {
            completepack(v,w,m);
        }
        else
        {
            int k=1;
            while(k<c)
            {
                zeroonepack(k*v,k*w,m);
                c-=k;
                k*=2;
            }
            zeroonepack(c*v,c*w,m);
        }
    }
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            if(n==0&&m==0)
            {
                return 0;
            }
            memset(f,0,sizeof(f));
            for(int i=1;i<=n;++i)
            {
                scanf("%d",&w[i]);//
            }
            for(int i=1;i<=n;++i)
            {
                scanf("%d",&c[i]);//
            }
            for(int i=1;i<=n;++i)
            {
                multipack(w[i],w[i],m,c[i]);
            }
            int sum=0;
            for(int i=1;i<=m;++i)
            {
                if(f[i]==i)
                {
                    ++sum;
                }
            }
            printf("%d\n",sum);///
        }
        return 0;
    }
    背包
  • 相关阅读:
    JS实现双击内容变为可编辑状态
    DataTables 1.10.x与1.9.x参数名对照表
    div里 datapicker显示异常的情况之一
    javascript 添加行,删除行,datepicker获取当前日期和上一个月日期并设置格式,笔记
    jQuery 实现添加表格行,删除行,调用日期控件
    c# webbrowser控件内核版本强制修改
    【.net】获取网页CDM的下载链接的地址
    MySQL 密码增强插件
    跟我一起学extjs5(42--单个模块的数据新增方式)
    给 Android 开发人员的 RxJava 具体解释
  • 原文地址:https://www.cnblogs.com/yoududezongzi/p/11368456.html
Copyright © 2011-2022 走看看