• 从2017年暑假到现在手打的模板↑_↑


    Helloworld,我是来自湖南长沙的一枚蒟蒻,一个普通学生。(还有,我是男生).

    从2017年暑假开始,我才接触了c++这种语言,觉得很美妙,有一种无所不能的感觉。

    曾经,我只是接触过一部分这一类型的东东,也曾编程制作任务型和对抗型机器人(botball).

    希望自己能结合曾经的浅薄知识,对信息学有更深的认识,认真学习!

    很乐意交友,很乐意与大家交流学习哦。

    以下都是我学到的部分知识,大部分学自他人的博客,真的很感激各路大神。

    所以,我也十分乐意分享自己学习算法的理解和心得,希望大家多多关注!(关爱菜鸡,人人有责).

    一、

    求逆元-费马小定理

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long lol;
    
    int n,p;
    
    lol qpow(lol x)
    {
        int y=p-2;
        lol ans=1;
        while (y) {
            if (y&1) ans*=x,ans%=p;
            x*=x;x%=p;y/=2;
        }
        return ans;
    }
    
    inline void write(lol x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    
    int main()
    {
        scanf("%d%d",&n,&p);
        for (int i=1;i<=n;i++) {
            write(qpow(i)%p);
            putchar('
    ');
        }
        return 0;
    }
    View Code

    二、

    树状数组

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long lol;
    
    lol n,m;
    lol f[500010];
    
    lol lowbit(lol x)
    {
        return x&-x;
    }
    
    void add(lol x,lol k)
    {
        for (int i=x;i<=n;i+=lowbit(i)) f[i]+=k;
    }
    
    lol getsum(lol x)
    {
        lol ans=0;
        for (int i=x;i;i-=lowbit(i)) ans+=f[i];
        return ans;
    }
    
    int main()
    {
        cin>>n>>m;lol a;
        for (int i=1;i<=n;i++) scanf("%lld",&a),add(i,a);
        lol flag,x,y,k;
        for (int i=1;i<=m;i++) {
            scanf("%lld%lld",&flag,&x);
            if (flag==1) {
                scanf("%lld",&k);
                add(x,k);
            }
            if (flag==2) {
                scanf("%lld",&y);
                printf("%lld
    ",getsum(y)-getsum(x-1));
            }
        }
        return 0;
    }
    View Code

    三、

    最大流-Dinic

    #include <bits/stdc++.h>
    using namespace std;
    
    int cnt=-1,depth[10010],cur[10010],s,t,n,m;
    int next[200010],head[10010],v[200010],w[200010];
    
    int dfs(int u,int flow)
    {
        if (u==t) return flow;
        for (int& i=cur[u];i!=-1;i=next[i]) {
            if ((w[i]!=0)&&(depth[v[i]]==depth[u]+1)) {
                int di=dfs(v[i],min(flow,w[i]));
                if (di>0) {w[i]-=di;w[i^1]+=di;return di;}
            }
        }
        return 0;
    }
    
    bool bfs()
    {
        queue <int> q;
        memset(depth,0,sizeof(depth));
        while (!q.empty()) q.pop();
        q.push(s);depth[s]=1;
        do {
            int u=q.front();q.pop();
            for (int i=head[u];i!=-1;i=next[i]) {
                if ((w[i]>0)&&(depth[v[i]]==0)) {
                    q.push(v[i]);depth[v[i]]=depth[u]+1;
                }
            }
        }while(!q.empty());
        if (depth[t]>0) return 1;
        return 0;
    }
    
    int dinic()
    {
        int ans=0;
        while (bfs()) {
            for (int i=1;i<=n;i++) cur[i]=head[i];
            while (int d=dfs(s,3e8)) ans+=d;
        }
        return ans;
    }
    
    int main()
    {
        int a,b,c;
        cin>>n>>m>>s>>t;
        memset(head,-1,sizeof(head));
        memset(next,-1,sizeof(next));
        while (m--) {
            scanf("%d%d%d",&a,&b,&c);
            cnt++;v[cnt]=b;w[cnt]=c;
            next[cnt]=head[a];head[a]=cnt;
            cnt++;v[cnt]=a;w[cnt]=0;
            next[cnt]=head[b];head[b]=cnt;
        }
        cout<<dinic()<<endl;
        return 0;
    }
    View Code

     

    四、

    二分图-匈牙利算法

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m,e,girl[1005];
    bool used[1005],line[1005][1005];
    
    bool find(int x)
    {
        for (int j=1;j<=m;j++)
        if (line[x][j]&&!used[j]) {
            used[j]=1;
            if (!girl[j]||find(girl[j])) {
                girl[j]=x;return 1;
            }
        }
        return 0;
    }
    
    int main()
    {
        int x,y;
        cin>>n>>m>>e;
        for (int i=1;i<=e;i++)
        scanf("%d%d",&x,&y),line[x][y]=1;
        e=0;
        for (int i=1;i<=n;i++) {
            if (find(i)) e++;
            memset(used,0,sizeof(used));
        }
        cout<<e<<endl;
        return 0;
    }
    View Code

    五、

    扩展欧几里得

    #include <bits/stdc++.h>
    using namespace std;
    
    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()
    {
        int a,b,x,y;
        cin>>a>>b;
        exgcd(a,b,x,y);
        cout<<(x%b+b)%b<<endl;
        return 0;
    }
    View Code

    六、

    假的字符串Hash,其实是map

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    string s;
    map <string,int> mp;
    
    int main()
    {
        cin>>n;int ans=0;
        for (int i=1;i<=n;i++) {
            cin>>s;
            if (!mp.count(s)) ans++,mp[s]=1;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    七、

    克鲁斯卡尔

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m;
    int fa[5001];
    
    struct ed {
        int f,t,w;
    }e[400010];
    
    bool cmp(ed a,ed b)
    {
        return a.w<b.w;
    }
    
    void init()
    {
        for (int i=1;i<=n;i++) fa[i]=i;
    }
    
    int find(int a)
    {
        if (a==fa[a]) return a;
        return fa[a]=find(fa[a]);
    }
    
    void unionset(int a,int b)
    {
        int u=find(a),v=find(b);
        if (u!=v) fa[u]=v;
    }
    
    bool same(int u,int v)
    {
        return find(u)==find(v);
    }
    
    void kruskal()
    {
        int res=0;
        init();int cnt=0;
        sort(e+1,e+1+m,cmp);
        for (int i=1;i<=m;i++) {
            if (!same(e[i].f,e[i].t)) {
                res+=e[i].w;
                unionset(e[i].f,e[i].t);
                ++cnt;
            }
            if (cnt==n-1) break;
        }
        cout<<res<<endl;
    }
    
    int main()
    {
        cin>>n>>m;int x,y,w;
        for (int i=1;i<=m;i++) {
            scanf("%d%d%d",&x,&y,&w);
            e[i].f=x;e[i].t=y;e[i].w=w;
        }
        kruskal();
        return 0;
    }
    View Code

    八、

    LCA-倍增

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m,ss;
    int dep[500010];
    int dpt[500010][30];
    int cnt;
    int o[1000010];
    int s[1000010][2];
    
    void jia(int x,int y)
    {
        s[++cnt][1]=o[x];
        s[cnt][0]=y;o[x]=cnt;
    }
    
    void dfs(int x,int d)
    {
        dep[x]=d;
        for (int i=o[x];i;i=s[i][1]) {
            int y=s[i][0];
            if (!dep[y]) {
                dpt[y][0]=x;
                dfs(y,d+1);
            }
        }
    }
    
    void init()
    {
        for (int j=1;j<=19;j++)
        for (int i=1;i<=n;i++)
        dpt[i][j]=dpt[dpt[i][j-1]][j-1];
    }
    
    int lca(int a,int b)
    {
        if (dep[a]<dep[b]) swap(a,b);
        for (int j=19;j>=0;j--)
        if (dep[a]-(1<<j)>=dep[b]) a=dpt[a][j];
        if (a!=b) {
            for (int j=19;j>=0;j--)
            if (dpt[a][j]!=dpt[b][j])
            a=dpt[a][j],b=dpt[b][j];
            a=dpt[a][0];
        }
        return a;
    }
    
    int main()
    {
        int x,y;
        cin>>n>>m>>ss;
        for (int i=1;i<n;i++) {
            scanf("%d%d",&x,&y);
            jia(x,y);jia(y,x);
        }
        dfs(ss,1);init();
        for (int i=1;i<=m;i++) {
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    View Code

     

    九、

    最长公共子序列(离散+LIS法求LCS)

    #include <bits/stdc++.h>
    #define N 100010
    using namespace std;
    
    int len,b[N],f[N];
    int n,table[N],in[N];
    
    int main()
    {
        int a;
        cin>>n;
        for (int i=1;i<=n;i++) {
            scanf("%d",&a);
            table[a]=i;
        }
        for (int i=1;i<=n;i++)
        scanf("%d",&in[i]);
        for (int i=1;i<=n;i++) {
            if (table[in[i]]>b[len]) {
                b[++len]=table[in[i]];
                f[i]=len;
                continue;
            }
            int arr=lower_bound(b+1,b+1+len,table[in[i]])-b;
            b[arr]=table[in[i]];
            f[i]=arr;
        }
        cout<<len<<endl;
        return 0;
    }
    View Code

    十、

    归并排序求逆序对

    #include <bits/stdc++.h>
    using namespace std;
    
    int ans,n,a[100010],r[100010];
    
    void msort_nxd(int s,int t)
    {
        if (s==t) return;
        int mid=s+t>>1;
        msort_nxd(s,mid);
        msort_nxd(mid+1,t);
        int i=s,j=mid+1,k=s;
        while (i<=mid&&j<=t) {
            if (a[i]<=a[j]) {
                r[k]=a[i];i++;k++;
            }
            else {
                r[k]=a[j];j++;k++;
                ans+=mid-i+1;
            }
        }
        while (i<=mid) r[k++]=a[i++];
        while (j<=t) r[k++]=a[j++];
        for (int q=s;q<=t;q++) a[q]=r[q];
    }
    
    int main()
    {
        cin>>n;
        for (int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
        }
        msort_nxd(1,n);
        cout<<ans<<endl;
        return 0;
    }
    View Code

    十一、

    线段树

    #include <bits/stdc++.h>
    #define ll(x) ((x)<<1)
    #define rr(x) ((x)<<1|1)
    using namespace std;
    typedef long long lol;
    
    lol n,m,a[100010];
    lol sgm[100010*4],lazy[100010*4];
    
    void shang(lol r)
    {
        sgm[r]=sgm[ll(r)]+sgm[rr(r)];
    }
    
    void xia(lol r,lol z,lol y)
    {
        int k=z+y>>1;
        lazy[ll(r)]+=lazy[r];
        lazy[rr(r)]+=lazy[r];
        sgm[ll(r)]+=(k-z+1)*lazy[r];
        sgm[rr(r)]+=(y-k)*lazy[r];
        lazy[r]=0;
    }
    
    void js(lol r,lol z,lol y)
    {
        if (z==y) {
            sgm[r]=a[z];
            return;
        }
        int k=z+y>>1;
        js(ll(r),z,k);
        js(rr(r),k+1,y);
        shang(r);
    }
    
    void qjxg(lol r,lol z,lol y,lol zz,lol yy,lol v)
    {
        if (z>yy||y<zz) return;
        if (z>=zz&&y<=yy) {
            lazy[r]+=v;
            sgm[r]+=(y-z+1)*v;
            return;
        }
        if (lazy[r]) xia(r,z,y);
        int k=z+y>>1;
        if (zz<=k) qjxg(ll(r),z,k,zz,yy,v);
        if (yy>k) qjxg(rr(r),k+1,y,zz,yy,v);
        shang(r);
    }
    
    lol cx(lol r,lol z,lol y,lol zz,lol yy)
    {
        if (z>yy||y<zz) return 0;
        if (z>=zz&&y<=yy) return sgm[r];
        int k=z+y>>1;
        if (lazy[r]) xia(r,z,y);
        return cx(ll(r),z,k,zz,yy)+cx(rr(r),k+1,y,zz,yy);
    }
    
    int main()
    {
        cin>>n>>m;
        for (int i=1;i<=n;i++) {
            scanf("%lld",&a[i]);
        }
        js(1,1,n);
        lol flag,x,y,k;
        for (int i=1;i<=m;i++) {
            scanf("%lld",&flag);
            if (flag==1) {
                scanf("%lld%lld%lld",&x,&y,&k);
                qjxg(1,1,n,x,y,k);
            }
            else {
                scanf("%lld%lld",&x,&y);
                cout<<cx(1,1,n,x,y)<<endl;
            }
        }
        return 0;
    }
    View Code

    十二、

     SPFA

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m,st,d[10010];
    int cnt;
    int o[500010];
    int s[500010][3];
    
    void jia(int x,int y,int c)
    {
        s[++cnt][1]=o[x];
        s[cnt][0]=y;
        s[cnt][2]=c;o[x]=cnt;
    }
    
    queue <int> q;
    bool v[10010];
    
    void SPFA()
    {
        for (int i=1;i<=n;i++)
        d[i]=2147483647;
        v[st]=1;q.push(st);d[st]=0;
        while (!q.empty()) {
            int x=q.front();
            for (int i=o[x];i;i=s[i][1]) {
                int y=s[i][0];
                if (d[y]>d[x]+s[i][2]) {
                    d[y]=d[x]+s[i][2];
                    if (!v[y]) {
                        v[y]=1;
                        q.push(y);
                    }
                }
            }
            q.pop();v[x]=0;
        }
    }
    
    int main()
    {
        int x,y,c;
        cin>>n>>m>>st;
        for (int i=1;i<=m;i++) {
            scanf("%d%d%d",&x,&y,&c);
            jia(x,y,c);
        }
        SPFA();
        for (int i=1;i<=n;i++) {
            printf("%d ",d[i]);
        }
        cout<<endl;
        return 0;
    }
    View Code

     

     十三、

    树链剖分

    #include <bits/stdc++.h>
    #define ll(x) ((x)<<1)
    #define rr(x) ((x)<<1|1)
    using namespace std;
    typedef long long l;
    
    const int N=100010;l n,m,r,p,cnt,dfscnt;
    l d[N],id[N],f[N],son[N],top[N],siz[N],sgm[N*4],lazy[N*4],a[N],w[N],o[N],s[N*2][2];
    
    void jia(l x,l y) {s[++cnt][1]=o[x];s[cnt][0]=y;o[x]=cnt;}
    
    void dfs(l x,l fa,l dep)
    {
        f[x]=fa;d[x]=dep;siz[x]=1;l mm=-1;
        for (int i=o[x];i;i=s[i][1]) {
            if (s[i][0]!=fa) {
                dfs(s[i][0],x,dep+1);siz[x]+=siz[s[i][0]];
                if (siz[s[i][0]]>mm) son[x]=s[i][0],mm=siz[s[i][0]];
            }
        }
    }
    
    void build(l x,l tp)
    {
        id[x]=++dfscnt;top[x]=tp;a[dfscnt]=w[x];
        if (son[x]) build(son[x],tp);
        for (int i=o[x];i;i=s[i][1])
        if ((s[i][0]!=f[x])&&(son[x]!=s[i][0])) build(s[i][0],s[i][0]);
    }
    
    void xia(l r,l z,l y)
    {
        l k=z+y>>1;lazy[ll(r)]+=lazy[r];lazy[rr(r)]+=lazy[r];
        sgm[ll(r)]+=(k-z+1)*lazy[r];
        sgm[rr(r)]+=(y-k)*lazy[r];
        sgm[ll(r)]%=p;sgm[ll(r)]%=p;lazy[r]=0;
    }
    
    void js(l r,l z,l y)
    {
        if (z==y) {sgm[r]=a[z];if (sgm[r]>p) sgm[r]%=p;return;}
        l k=z+y>>1;js(ll(r),z,k);js(rr(r),k+1,y);sgm[r]=(sgm[ll(r)]+sgm[rr(r)])%p;
    }
    
    void qjxg(l r,l z,l y,l zz,l yy,l v)
    {
        if (z>yy||y<zz) return;
        if (z>=zz&&y<=yy) {
            lazy[r]+=v;sgm[r]+=(y-z+1)*v;return;}
        if (lazy[r]) xia(r,z,y);l k=z+y>>1;
        if (zz<=k) qjxg(ll(r),z,k,zz,yy,v);if (yy>k) qjxg(rr(r),k+1,y,zz,yy,v);
        sgm[r]=(sgm[ll(r)]+sgm[rr(r)])%p;
    }
    
    l cx(l r,l z,l y,l zz,l yy)
    {
        if (z>yy||y<zz) return 0;
        if (z>=zz&&y<=yy) return sgm[r]%p;
        l k=z+y>>1;if (lazy[r]) xia(r,z,y);
        return (cx(ll(r),z,k,zz,yy)+cx(rr(r),k+1,y,zz,yy))%p;
    }
    
    l qiulu(l x,l y)
    {
        l ans=0;while (top[x]!=top[y]) {
            if (d[top[x]]<d[top[y]]) swap(x,y);
            ans+=cx(1,1,n,id[top[x]],id[x]);ans%=p;x=f[top[x]];
        }
        if (d[x]>d[y]) swap(x,y);ans+=cx(1,1,n,id[x],id[y]);ans%=p;
        return ans;
    }
    
    void jialu(l x,l y,l v)
    {
        v%=p;while (top[x]!=top[y]) {
            if (d[top[x]]<d[top[y]]) swap(x,y);
            qjxg(1,1,n,id[top[x]],id[x],v);x=f[top[x]];
        }
        if (d[x]>d[y]) swap(x,y);qjxg(1,1,n,id[x],id[y],v);
    }
    
    int main()
    {
        l x,y,v,flag;cin>>n>>m>>r>>p;for (int i=1;i<=n;i++) scanf("%lld",&w[i]);
        for (int i=1;i<n;i++) {scanf("%lld%lld",&x,&y);jia(x,y);jia(y,x);}dfs(r,0,1);build(r,r);js(1,1,n);
        for (int i=1;i<=m;i++) {scanf("%lld",&flag);
            if (flag==1) {scanf("%lld%lld%lld",&x,&y,&v);jialu(x,y,v);}
            if (flag==2) {scanf("%lld%lld",&x,&y);printf("%lld
    ",qiulu(x,y));}
            if (flag==3) {scanf("%lld%lld",&x,&v);v%=p;qjxg(1,1,n,id[x],id[x]+siz[x]-1,v);}
            if (flag==4) {scanf("%lld",&x);printf("%lld
    ",cx(1,1,n,id[x],id[x]+siz[x]-1)%p);}
        }
        return 0;
    }
    View Code

     十四、

    最小费用最大流

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=5010,M=100010,inf=2e9;
    int head,tail,cnt=-1,n,m,s,t,cost=0;
    int q[N*10],v[N],ss[M*2][4],o[N],d[N],vis[N];
    
    void jia(int a,int b,int c,int cc)
    {
        ss[++cnt][0]=b;ss[cnt][1]=o[a];
        ss[cnt][2]=c;ss[cnt][3]=cc;o[a]=cnt;
        ss[++cnt][0]=a;ss[cnt][1]=o[b];
        ss[cnt][2]=0;ss[cnt][3]=-cc;o[b]=cnt;
    }
    
    int dfs(int x,int flow)
    {
        v[x]=1;int rest=0;if (x==t) return flow;
        for (int i=o[x];i!=-1;i=ss[i][1]) {
            if ((d[ss[i][0]]==d[x]-ss[i][3])&&(v[ss[i][0]]==0)&&(ss[i][2]!=0)) {
                int di=dfs(ss[i][0],min(flow-rest,ss[i][2]));
                if (di>0) {rest+=di;ss[i][2]-=di;ss[i^1][2]+=di;}
            }
        }
        return rest;
    }
    
    bool spfa()
    {
        for (int i=1;i<=n;i++) d[i]=inf,vis[i]=0;
        head=1;tail=2;q[1]=t;d[t]=0;vis[t]=1;
        while (head!=tail) {
            int u=q[head];
            for (int i=o[u];i!=-1;i=ss[i][1]) {
                if ((d[ss[i][0]]>d[u]-ss[i][3])&&(ss[i^1][2]!=0)) {
                    d[ss[i][0]]=d[u]-ss[i][3];
                    if (!vis[ss[i][0]]) {
                        vis[ss[i][0]]=1;q[tail++]=ss[i][0];if (tail==n+1) tail=1;
                    }
                }
            }
            q[head++]=0;vis[u]=0;if (head==n+1) head=1;
        }
        return d[s]!=inf;
    }
    
    void FU_DUI_SUAN_FA_BO_DA_JING_SHEN()
    {
        int ans=0,cntt=1;
        while (spfa()) {
            v[t]=1;
            while (v[t]) {
                memset(v,0,sizeof(v));
                int l=dfs(s,inf);ans+=l;cost+=l*d[s];
            }
        }
        cout<<ans<<" "<<cost<<endl;
    }
    
    int main()
    {
        int a,b,c,cc;
        memset(o,-1,sizeof(o));
        cin>>n>>m>>s>>t;
        for (int i=1;i<=m;i++) {
            scanf("%d%d%d%d",&a,&b,&c,&cc);
            jia(a,b,c,cc);
        }
        FU_DUI_SUAN_FA_BO_DA_JING_SHEN();
        return 0;
    }
    View Code

    十五、

    堆(手打)

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,flag,heap[1000010],heapsize;
    
    void jiaru(int d)
    {
        int now,next;heap[++heapsize]=d;now=heapsize;
        while (now>1) {
            next=now>>1;if (heap[now]>=heap[next]) break;
            swap(heap[now],heap[next]);now=next;
        }
        return;
    }
    
    int shanchu_quchu()
    {
        int now,next,res;res=heap[1];heap[1]=heap[heapsize--];now=1;
        while (now*2<=heapsize) {
            next=now*2;
            if (next<heapsize&&heap[next+1]<heap[next]) next++;
            if (heap[now]<=heap[next]) break;swap(heap[now],heap[next]);
            now=next;
        }
        return res;
    }
    
    int main()
    {
        cin>>n;int x;
        while (n--) {
            scanf("%d",&flag);
            if (flag==1) {scanf("%d",&x);jiaru(x);}
            if (flag==2) {printf("%d
    ",heap[1]);}
            if (flag==3) {int daiti=shanchu_quchu();}
        }
        return 0;
    }
    View Code

     

    十六、

    优先队列(STL)

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,flag,a;
    priority_queue <int> heap;
    
    int main() {
        cin>>n;
        for (int i=1;i<=n;i++) {
            cin>>flag;
            if (flag==1) {
                cin>>a;
                heap.push(-a);
            }
            else if (flag==2) {
                int f=heap.top();
                cout<<-f<<endl;
            }
            else heap.pop();
        }
        return 0;
    }
    View Code

     

    十七、

    迪杰斯特拉(堆优化版本)

    #include <bits/stdc++.h>
    #define MAXN 10010
    using namespace std;
    typedef pair<int,int>Pair;
    
    struct node {
      int u,w,v,next;
    }e[500010];
    
    int dis[MAXN],st[MAXN];
    bool flag[MAXN];
    int tot,start,n,m,x,y,z;
    
    void add(int x,int y,int z)
    {
      e[++tot].u=x;e[tot].v=y;
      e[tot].w=z;
      e[tot].next=st[x];st[x]=tot;
    }
    
    int dijsktra(int start)
    {
      memset(dis,127,sizeof dis);
      memset(flag,0,sizeof flag);
      dis[start]=0;priority_queue< Pair,vector<Pair>,greater<Pair> >que;
      que.push(make_pair(dis[start],start));
      while (!que.empty()) {
        Pair now=que.top();que.pop();
        if (flag[now.second]) continue;
        flag[now.second]=1;
        for (int i=st[now.second];i;i=e[i].next)
        if (dis[now.second]+e[i].w<dis[e[i].v]) {
          dis[e[i].v]=dis[now.second]+e[i].w;
          if (!flag[e[i].v]) que.push(make_pair(dis[e[i].v],e[i].v));
        }
      }
      for (int i=1;i<=n;i++) {
        if (dis[i]==2139062143) dis[i]=2147483647;
        printf("%d ",dis[i]);
      }
    }
    int main()
    {
      scanf("%d%d%d",&n,&m,&start);
      for (int i=1;i<=m;i++) {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
      }
      dijsktra(start);
    }
    View Code

     

    十八、

    迪杰斯特拉(线段树版本)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn =10007;
    const int maxm = 500007;
    const int INF = 0x7fffffff;
    int n,m;
    
    inline int read()
    {
      int x=0;
      char c=getchar();
      while (c<'0'||c>'9') c=getchar();
      while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
      return x;
    }
    
    struct node{
      int v,next,w;
    }edge[maxm];
    
    int num=0,head[maxn];
    
    inline void add_edge(int a,int b,int c) {
      edge[++num].v=b;edge[num].w=c;edge[num].next=head[a];head[a]=num;
    }
    
    int dis[maxn],ans[maxn],s,t;
    int tree[maxn<<2],leaf;
    
    inline int check(int i,int j) {
      return dis[i]<dis[j]?i:j;
    }
    
    inline void build() {
      std::memset(dis,0x3f,sizeof dis);
      for (leaf=1;leaf<=n;leaf<<=1);--leaf;
      for (int i=1;i<=n;++i)tree[leaf+i]=i;
    }
    
    inline void modify(int x,int y) {
      dis[x]=y,x+=leaf,x>>=1;
      while(x) tree[x]=check(tree[x<<1],tree[x<<1|1]),x=x>>1;
    }
    
    void dijkstra(int s) {
      build();dis[s]=0;int u=s;
      for (int i=1;i<=n;++i) {
        ans[u]=dis[u];
        const int disu=dis[u];
        modify(u,INF); 
        for (int j=head[u];j;j=edge[j].next){
          int v=edge[j].v;
          if (dis[v]<INF&&dis[v]>disu+edge[j].w)
            modify(v,disu+edge[j].w);
        }
        u=tree[1];
      }
    }
    
    inline void put(int x)
    {
      if (x>9) put(x/10);
      putchar(x%10+48);   
    }
    
    int main() {
        int k;
        n=read(),m=read(),k=read();
        for (int a,b,c,i=1;i<=m;++i) {
            a=read(),b=read(),c=read();
            add_edge(a,b,c);
      }
      dijkstra(k);
      for (int i=1;i<=n;++i) {
        if (dis[i]==0x3f3f3f3f) ans[i]=INF;
          put(ans[i]);putchar(' ');
      }
      putchar('
    ');
      return 0;
    }
    View Code

    十九、

    普通平衡树(splay)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=100010;
    int ch[N][2],f[N],ky[N],ct[N],siz[N],sz,rt;
    
    void clear(int x)
    {
        ch[x][0]=ch[x][1]=f[x]=siz[x]=ct[x]=ky[x]=0;
        return;
    }
    
    bool get(int x)
    {
        return ch[f[x]][1]==x;
    }
    
    void update(int x)
    {
        if (x) {
            siz[x]=ct[x];
            if (ch[x][0]) siz[x]+=siz[ch[x][0]];
            if (ch[x][1]) siz[x]+=siz[ch[x][1]];
        }
        return;
    }
    
    void rotate(int x)
    {
        int old=f[x],oldf=f[old],which=get(x);
        ch[old][which]=ch[x][which^1];f[ch[old][which]]=old;
        ch[x][which^1]=old;f[old]=x;f[x]=oldf;
        if (oldf) ch[oldf][ch[oldf][1]==old]=x;
        update(old);update(x);
    }
    
    void splay(int x)
    {
        for (int fa;fa=f[x];rotate(x))
        if (f[fa]) rotate((get(x)==get(fa))?fa:x);
        rt=x;return;
    }
    
    void insert(int v)
    {
        if (!rt) {
            sz++;ch[sz][0]=ch[sz][1]=f[sz]=0;
            ky[sz]=v;ct[sz]=1;siz[sz]=1;rt=sz;
            return;
        }
        int now=rt,fa=0;
        while (1) {
            if (ky[now]==v) {
                ct[now]++;
                update(now);update(fa);
                splay(now);break;
            }
            fa=now;now=ch[now][ky[now]<v];
            if (!now) {
                sz++;ch[sz][0]=ch[sz][1]=0;ky[sz]=v;siz[sz]=1;
                ct[sz]=1;f[sz]=fa;ch[fa][ky[fa]<v]=sz;
                update(fa);splay(sz);break;
            }
        }
        return;
    }
    
    int find(int v)
    {
        int ans=0,now=rt;
        while (1) {
            if (v<ky[now]) now=ch[now][0];
            else {
                ans+=(ch[now][0]?siz[ch[now][0]]:0);
                if (v==ky[now]) {splay(now);return ans+1;}
                ans+=ct[now];now=ch[now][1];
            }
        }
        return 0;
    }
    
    int findx(int x)
    {
        int now=rt;
        while (1) {
            if (ch[now][0]&&x<=siz[ch[now][0]]) now=ch[now][0];
            else {
                int tt=(ch[now][0]?siz[ch[now][0]]:0)+ct[now];
                if (x<=tt) return ky[now];
                x-=tt;now=ch[now][1];
            }
        }
        return 0;
    }
    
    int pre()
    {
        int now=ch[rt][0];
        while (ch[now][1]) now=ch[now][1];
        return now;
    }
    
    int next()
    {
        int now=ch[rt][1];
        while (ch[now][0]) now=ch[now][0];
        return now;
    }
    
    void del(int x)
    {
        int whatever=find(x);
        if (ct[rt]>1) {ct[rt]--;update(rt);return;}
        if (!ch[rt][0]&&!ch[rt][1]) {clear(rt);rt=0;return;}
        if (!ch[rt][0]) {
            int oldrt=rt;rt=ch[rt][1];f[rt]=0;clear(oldrt);return;
        }
        else if (!ch[rt][1]) {
            int oldrt=rt;rt=ch[rt][0];f[rt]=0;clear(oldrt);return;
        }
        int leftbig=pre(),oldrt=rt;
        splay(leftbig);
        ch[rt][1]=ch[oldrt][1];f[ch[oldrt][1]]=rt;
        clear(oldrt);update(rt);return;
    }
    
    int main()
    {
        int n,a,b;cin>>n;int rrr=0;
        while (n--) {
            scanf("%d%d",&a,&b);
            if (a==1) insert(b)/*,cout<<++rrr<<"i"<<endl*/;
            else if (a==2) del(b)/*,cout<<++rrr<<"d"<<endl*/;
            else if (a==3) printf("%d
    ",find(b))/*,cout<<++rrr<<"f"<<endl*/;
            else if (a==4) printf("%d
    ",findx(b))/*,cout<<++rrr<<"x"<<endl*/;
            else if (a==5) {insert(b);printf("%d
    ",ky[pre()]);del(b)/*,cout<<++rrr<<"p"<<endl*/;}
            else {insert(b);printf("%d
    ",ky[next()]);del(b)/*,cout<<++rrr<<"n"<<endl*/;}
        }
        return 0;
    }
    View Code

     

    二十、

    矩阵快速幂

    #include <bits/stdc++.h>
    using namespace std;
    
    long long n,p;
    long long mod=1e9+7;
    long long ans[105][105];
    long long a[105][105],b[105][105];
    
    void lu() {
        memcpy(b,ans,sizeof(ans));
        memset(ans,0,sizeof(ans));
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                for (int k=1;k<=n;k++)
                    ans[i][j]=(ans[i][j]+(b[i][k]*a[k][j])%mod)%mod;
    }
    
    void ge() {
        memcpy(b,a,sizeof(a));
        memset(a,0,sizeof(a));
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                for (int k=1;k<=n;k++)
                    a[i][j]=(a[i][j]+(b[i][k]*b[k][j])%mod)%mod;
    }
    
    int main() {
        cin>>n>>p;p--;
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                cin>>ans[i][j];
        memcpy(a,ans,sizeof(a));
        while (p) {
            if (p&1) lu();
            ge();p>>=1;
        }
        for (int i=1;i<=n;i++) {
            for (int j=1;j<=n;j++)
                cout<<ans[i][j]<<' ';
            cout<<endl;
        }
        return 0;
    }
    View Code

    二十一、

    普通平衡树(treap)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=11e4,big=2e9;
    int top,sz,ch[N][2],siz[N],rk[N],num[N],f[N],small=-big;
    
    void update(int x)
    {
        siz[x]=siz[ch[x][1]]+siz[ch[x][0]]+1;
        return;
    }
    
    int rotate(int j,int get)
    {
        int nson=ch[j][get],other=(get^1);
        ch[j][get]=ch[nson][other];
        ch[nson][other]=j;
        update(j);update(nson);
        return nson;
    }
    
    int insert(int j,int v)
    {
        if (!j) {
            sz++;siz[sz]=1;
            num[sz]=v;rk[sz]=rand();
            return sz;
        }
        bool get=(num[j]<=v);
        siz[j]++;ch[j][get]=insert(ch[j][get],v);
        if (rk[j]>rk[ch[j][get]]) return rotate(j,get);
        return j;
    }
    
    int del(int j,int v)
    {
        if (num[j]==v) {
            if (ch[j][0]&&ch[j][1]) {
                int son=ch[j][0],fa=0;
                while (ch[son][1]) fa=son,son=ch[son][1],siz[fa]--;
                if (son==ch[j][0]) {
                    ch[son][1]=ch[j][1];rk[son]=rk[j];
                    siz[son]=siz[j]-1;return son;
                }
                ch[fa][1]=ch[son][0];ch[son][0]=ch[j][0];
                ch[son][1]=ch[j][1];rk[son]=rk[j];siz[son]=siz[j]-1;
                return son;
            }
            if (ch[j][0]) return ch[j][0];
            return ch[j][1];
        }
        int get=(num[j]<v);
        ch[j][get]=del(ch[j][get],v);siz[j]--;return j;
    }
    
    int newww(int j,int x)
    {
        if (!j) return -1;
        if (num[j]==x) {
            int ans=newww(ch[j][0],x);
            return ans==-1?j:ans;
        }
        if (num[j]>x) return newww(ch[j][0],x);
        return newww(ch[j][1],x);
    }
    
    int find(int i,int j,int x)
    {
        if (i==j) return siz[ch[i][0]]+1;
        if (num[i]>=x) return find(ch[i][0],j,x);
        return find(ch[i][1],j,x)+siz[ch[i][0]]+1;
    }
    
    int findx(int j,int x)
    {
        if (siz[ch[j][0]]==x-1) return num[j];
        if (siz[ch[j][0]]>=x) return findx(ch[j][0],x);
        return findx(ch[j][1],x-siz[ch[j][0]]-1);
    }
    
    int pre(int j,int x)
    {
        if (!j) return small;
        if (num[j]<x) return max(num[j],pre(ch[j][1],x));
        return pre(ch[j][0],x);
    }
    
    int next(int j,int x)
    {
        if (!j) return big;
        if (num[j]>x) return min(num[j],next(ch[j][0],x));
        return next(ch[j][1],x);
    }
    
    int main()
    {
        srand(time(NULL));
        int n,m,x;cin>>n;
        while (n--) {
            scanf("%d%d",&m,&x);
            if (m==1) top=insert(top,x);
            if (m==2) top=del(top,x);
            if (m==3) printf("%d
    ",find(top,newww(top,x),x));
            if (m==4) printf("%d
    ",findx(top,x));
            if (m==5) printf("%d
    ",pre(top,x));
            if (m==6) printf("%d
    ",next(top,x));
        }
        return 0;
    }
    View Code

    二十二、

    线性筛素数(欧拉筛)

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m;
    int prime[10000010];
    bool isprime[10000010];
    int primesize;
    
    int gi() {
        char c=getchar();int a=0;bool f=0;
        while (c>'9'||c<'0') {if (c=='-') f=1;c=getchar();}
        while (c>='0'&&c<='9') {a=a*10+c-'0';c=getchar();}
        return f?-a:a;
    }
    
    void shai(int listsize) {
        memset(isprime,true,sizeof(isprime));
        isprime[1]=false;
        for (int i=2;i<=listsize;i++) {
            if (isprime[i]) prime[++primesize]=i;
            for (int j=1;j<=primesize&&i*prime[j]<=listsize;j++) {
                isprime[i*prime[j]]=false;
                if (i%prime[j]==0) break;
            }
        }
    }
    
    int main() {
        n=gi();m=gi();
        shai(n);
        for (int i=1;i<=m;i++) {
            int p=gi();
            if (isprime[p]==true) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
        return 0;
    }
    View Code

     

    二十三、

    KMP算法 字符串匹配

    #include <bits/stdc++.h>
    using namespace std;
    
    int kmp[1000010];
    char a[1000010],b[1000010];
    
    int main()
    {
        scanf("%s%s",a,b);
        int la=strlen(a),lb=strlen(b),k=0;
        for (int i=1;i<lb;i++) {
            while (k&&b[i]!=b[k]) k=kmp[k];
            kmp[i+1]=(b[i]==b[k])?++k:0;
        }
        k=0;
        for (int i=0;i<la;i++) {
            while (k&&a[i]!=b[k]) k=kmp[k];
            k+=(a[i]==b[k])?1:0;
            if (k==lb) printf("%d
    ",i-lb+2);
        }
        for (int i=1;i<=lb;i++) printf("%d ",kmp[i]);
        return 0;
    }
    View Code

    二十四、

    tarjan缩点+最短路

    #include <bits/stdc++.h>
    using namespace std;
    
    int last[100100],len=0,sccno[10010]={0},scc=0,n,m,u,v,w[10010]={0};
    int dfn[10010]={0},low[10010]={0},dfscnt=0,wscc[10010]={0};
    int f[100010]={0},t[100010]={0},ans=-2147483648,dis[10010]={0};
    bool vis[10010];
    
    stack <int> s;
    
    struct edge {
        int next,to;
    }e[100100];
    
    int gi() {
        char c=getchar();bool f=0;int a=0;
        while (c<'0'||c>'9') {if (c=='-') f=1;c=getchar();}
        while (c>='0'&&c<='9') {a=a*10+c-'0';c=getchar();}
        return f?-a:a;
     }
    
    void add(int x,int y) {
        e[++len].to=y;
        e[len].next=last[x];
        last[x]=len;
     }
    
    void init() {
        memset(last,-1,sizeof(last));
        n=gi();m=gi();
        for (int i=1;i<=n;i++) w[i]=gi();
        for (int i=1;i<=m;i++) {
            u=gi();v=gi();add(u,v);f[i]=u;t[i]=v;
         }
     }
    
    int tarjan(int r) {
        s.push(r);
        dfn[r]=low[r]=++dfscnt;
        for (int i=last[r];i!=-1;i=e[i].next) {
            int y=e[i].to;
            if (!dfn[y]) {tarjan(y);low[r]=min(low[r],low[y]);}
            else if (!sccno[y]) low[r]=min(low[r],dfn[y]);
         }
        if (dfn[r]==low[r]) {
            scc++;
            while (1) {
                int x=s.top();sccno[x]=scc;wscc[scc]+=w[x];
                s.pop();if (x==r) break;
             }
         }
     }
    
    void build() {
        len=0;
        memset(last,-1,sizeof(last));
        for (int i=1;i<=m;i++) {
            if (sccno[f[i]]!=sccno[t[i]]) add(sccno[f[i]],sccno[t[i]]);
         }
     }
    
    int bfs(int x) {
        memset(dis,-1,sizeof(dis));
        memset(vis,false,sizeof(vis));
        dis[x]=wscc[x];
        queue <int> q;
        vis[x]=true;q.push(x);
        while (!q.empty()) {
            int u=q.front();q.pop();vis[u]=false;
            for (int i=last[u];i!=-1;i=e[i].next) {
                int v=e[i].to;
                if (dis[v]<dis[u]+wscc[v]) {
                    dis[v]=dis[u]+wscc[v];
                    if (!vis[v]) {vis[v]=true;q.push(v);}
                 }
             }
         }
        for (int i=1;i<=scc;i++) ans=max(dis[i],ans);
     }
    
    int main() {
        init();
        for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
        build();
        for (int i=1;i<=scc;i++) bfs(i);
        printf("%d
    ",ans);
        return 0;
     }
    View Code

     

    二十五、

    主席树

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=300010;
    struct value {int x,id;} a[N];
    struct node {int l,r,sum;} ch[N*20];
    int rank[N],root[N],cnt,n,m;
    bool cmp(value x,value y) {return x.x<y.x;}
    
    void init()
    {
        cnt=1;
        root[0]=0;
        ch[0].l=ch[0].r=ch[0].sum;
    }
    
    void update(int num,int &rt,int l,int r)
    {
        ch[cnt++]=ch[rt];
        rt=cnt-1;
        ++ch[rt].sum;
        if (l==r) return;
        int mid=l+r>>1;
        if (num<=mid) update(num,ch[rt].l,l,mid);
        else update(num,ch[rt].r,mid+1,r);
    }
    
    int query(int i,int j,int k,int l,int r)
    {
        int d=ch[ch[j].l].sum-ch[ch[i].l].sum;
        if (l==r) return l;
        int mid=l+r>>1;
        if (k<=d) return query(ch[i].l,ch[j].l,k,l,mid);
        else return query(ch[i].r,ch[j].r,k-d,mid+1,r);
    }
    
    int main()
    {
        cin>>n>>m;
        for (int i=1;i<=n;++i) {
            scanf("%d",&a[i].x);
            a[i].id=i;
        }
        sort(&a[1],&a[n+1],cmp);
        for (int i=1;i<=n;++i)
            rank[a[i].id]=i;
        init();
        for (int i=1;i<=n;++i) {
            root[i]=root[i-1];
            update(rank[i],root[i],1,n);
        }
        int l,r,k;
        for (int i=1;i<=m;++i) {
            scanf("%d%d%d",&l,&r,&k);
            printf("%d
    ",a[query(root[l-1],root[r],k,1,n)].x);
        }
    }
    View Code

    二十六、

    字典树(trie树)

    #include <bits/stdc++.h>
    using namespace std;
    
    char s[100];
    const int N=2000010;
    int tot=1,tree[N][26],n;
    
    void insert(char *s,int rt)
    {
        for (int i=0;s[i];i++) {
            int x=s[i]-'a';
            if (!tree[rt][x]) tree[rt][x]=++tot;
            rt=tree[rt][x];
        }
    }
    
    bool find(char *s,int rt)
    {
        for (int i=0;s[i];i++) {
            int x=s[i]-'a';
            if (!tree[rt][x]) return 0;
            rt=tree[rt][x];
        }
        return 1;
    }
    
    int main()
    {
        tot=0;int rt=1;
        scanf("%d",&n);
        for (int i=1;i<=n;i++) {scanf("%s",s);insert(s,rt);}
        scanf("%d",&n);
        for (int i=1;i<=n;i++) {
            scanf("%s",s);
            if (find(s,rt)) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    View Code

    二十七、

    快速排序

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,a[100010]={0};
    
    inline void qsort(int l,int r)
    {
        if(l==r) return;
        int i=l,j=r,mid=a[(l+r)>>1];
        do {
            while (a[i]<mid) i++;
            while (a[j]>mid) j--;
            if (i<=j)
            {
                swap(a[i],a[j]);
                i++;j--;
            }
        } while(i<=j);
        if (l<j) qsort(l,j);
        if (i<r) qsort(i,r);
    }
    
    int main()
    {
        while (scanf("%d",&n)!=EOF)
        {
            for (int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
            }
            qsort(1,n);
            for (int i=1;i<=n;i++)
                printf("%d ",a[i]);
            printf("
    ");
        }
        return 0;
    }
    View Code

    二十八、

    FFT快速傅里叶(假的 其实是python)

    print(int(input())*int(input())) if input() else 0
    View Code

    二十九、

    并查集

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 10000+5
    #define INF2 200000+5
    
    int n,m; 
    
    struct Node{
        int rank;
        int father;
    }node[INF+1];
    
    int get_bigfather(int k)
    {
        if(node[k].father==k)
            return k;
        else
        {
            node[k].father=get_bigfather(node[k].father);
            return node[k].father;
        }    
    }
    
    void merge(int u,int v)
    {
        u=get_bigfather(u);
        v=get_bigfather(v);
        if(node[u].rank>node[v].rank) 
            node[v].father=u;
        else
        {
            node[u].father=v;
            if(node[u].rank==node[v].rank)
                node[v].rank++;
        }
    }
    
    int main() 
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            node[i].father=i;
        for(int i=1;i<=m;i++)
        {
            int temp,u,v;
            scanf("%d%d%d",&temp,&u,&v);
            if(temp==1)
                merge(u,v);
            else
            {
                if(get_bigfather(u)==get_bigfather(v))
                    printf("Y
    ");
                else
                    printf("N
    ");
            }
        }
        return 0; 
    }
    View Code

    三十、

    dfs版spfa判断负环

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m,cnt,flag;
    int head[10010];
    bool vis[10010];
    double dis[10010];
    
    struct node{
    int to,next;double v;
    }edge[10010];
    
    int read()
    {
        int x=0,w=1;char ch=getchar();
        while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return x*w;
    }
    
    void add(int x,int y,double v)
    {
        cnt++;
        edge[cnt].to=y;
        edge[cnt].next=head[x];
        edge[cnt].v=v;
        head[x]=cnt;
    }
    
    void spfa(int k,double jian)
    {
        vis[k]=1;
        int v;
        for(int i=head[k];i;i=edge[i].next)
        {
            v=edge[i].to;
            if(dis[v]>dis[k]+edge[i].v-jian)
            {
                if(vis[v])
                {
                    flag=1;
                    return;
                }
                dis[v]=dis[k]+edge[i].v-jian;
                spfa(v,jian);
                if(flag) return;
            }
        }
        vis[k]=0;
    }
    
    bool check(double mid)
    {
        flag=0;
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            spfa(i,mid);
            if(flag) return 1;
        }
        return 0;
    }
    
    int main()
    {
        int x,y;
        double z;
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();
            scanf("%lf",&z);
            add(x,y,z);
        }
        double l=-10000000,r=10000000,mid;
        while(r-l>1e-10)
        {
            mid=(l+r)/2;
            if(check(mid))
            {
                r=mid;
            }
            else
            {
                l=mid;
            }
        }
        printf("%.8lf",mid);
        return 0;
    }
    View Code

    三十一、

    BF算法(暴风算法)

    #include <bits/stdc++.h>
    using namespace std;
    
    int index_bf(char *s,char *t,int pos);  
    int index_bf_self(char *s,char *t,int index);  
    
    int main()  
    {  
        char s[]="6he3wor";
        char t[]="3wor";  
        int m=index_bf(s,t,2);
        printf("index_bf:%d
    ",m);  
        m=index_bf_self(s,t,2);
        printf("index_bf_self:%d
    ",m);  
        exit(0);  
    }  
    
    int index_bf(char *s,char *t,int pos)  
    {  
        int i,j;  
        if(pos>=1 && pos <=s[0]-'0')  
        {  
            i=pos;  
            j=1;  
            while(i<=s[0]-'0'&&j<=t[0]-'0')  
            {  
                if(s[i]==t[j])  
                {  
                    i++;  
                    j++;  
                }  
                else   
                {  
                    j=1;  
                    i=i-j+2;  
                }  
                if(j>t[0]-'0')  
                {  
                    return i-t[0]+'0';  
                }  
            }  
            return -1;  
        }  
        else   
        {  
            return -1;  
        }  
    }  
    
    int index_bf_self(char *s,char *t,int index)  
    {  
        int i=index,j=0;  
        while(s[i]!='')  
        {  
            while(*(t+j)!='' && *(s+i+j)!='')  
            {  
                if(*(t+j)!=*(s+i+j))  
                    break;  
                j++;  
            }  
            if(*(t+j)=='')  
            {  
                return i;  
            }  
            i++;  
            j=0;  
        }  
        return -1;  
    }
    View Code

    三十二、

    高斯消元法Gauss

    //Guss
    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    double f[105][105];
    const double eps=1e-8;
    
    int main()
    {
        scanf("%d",&n);
        for (int i=0;i<n;i++)//读入系数和值
        for (int j=0;j<=n;j++) scanf("%lf",&f[i][j]);
        for (int i=0;i<n;i++) {
            int ch=i;
            for (int j=i;j<n;j++)//选择绝对值最大的减少误差
            if (fabs(f[j][i]-f[ch][i])<=eps) ch=j;
            for (int j=0;j<=n;j++) swap(f[i][j],f[ch][j]);//交换
            if (fabs(f[i][i])<=eps) {//无解情况
                printf("No Solution
    ");
                return 0;//如果当前位置为零 则无解 0x=A
            }
            for (int j=i+1;j<=n;j++) f[i][j]/=f[i][i];//系数化1
            //自己那位不必要除 无影响
            for (int j=0;j<n;j++)
            if (i!=j)
            for (int k=i+1;k<=n;k++) f[j][k]-=f[j][i]*f[i][k];
            //加减法去掉系数值
        }
        for (int i=0;i<n;i++) printf("%.2lf
    ",f[i][n]);//输出
        return 0;
    }
    View Code

    三十三、

    扫描线(洛谷 ‘楼房’)

    #include <bits/stdc++.h>
    #define N 100010
    using namespace std;
    
    int n,cnt,num;
    multiset <int> s;
    
    struct thing {int h,l,r;}a[N];
    
    struct lines {int up,x,k;}l[N*2];
    
    struct anspr {int ax,ay;}ans[N*4];
    
    bool cmp(lines i,lines j)
    {
        if (i.x!=j.x) return i.x<j.x;
        if (i.k!=j.k) return i.k<j.k;
        if (i.k==1) return i.up>j.up;
        if (i.k==2) return i.up<j.up;
    }
    
    int main()
    {
        cin>>n;
        for (int i=1;i<=n;i++) {
            int q,w,e;
            scanf("%d%d%d",&q,&w,&e);
            a[i].h=q,a[i].l=w,a[i].r=e;
            l[++cnt].up=q;l[cnt].x=w,l[cnt].k=1;
            l[++cnt].up=q;l[cnt].x=e,l[cnt].k=2;
        }
        sort(l+1,l+1+cnt,cmp);
        s.insert(0);
        for (int i=1;i<=cnt;i++) {
            int mx=*s.rbegin();
            if (l[i].k==1) {
                if (l[i].up<=mx) s.insert(l[i].up);
                else {
                    ans[++num].ax=l[i].x;ans[num].ay=mx;
                    ans[++num].ax=l[i].x;ans[num].ay=l[i].up;
                    s.insert(l[i].up);
                }
            }
            if (l[i].k==2) {
                if (l[i].up==mx&&s.count(mx)==1) {
                    s.erase(mx);
                    ans[++num].ax=l[i].x;ans[num].ay=l[i].up;
                    ans[++num].ax=l[i].x;ans[num].ay=*s.rbegin();
                }
                else s.erase(s.find(l[i].up));
            }
        }
        cout<<num<<endl;
        for (int i=1;i<=num;i++)
        printf("%d %d
    ",ans[i].ax,ans[i].ay);
        return 0;
    }
    View Code

    三十四、

    Meeting-in-the-Middle

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=24;
    map <int,int> table;
    
    int bitcount(int x) {
        return x==0?0:bitcount(x/2)+(x&1);
    }//这个函数用来计算这个数在二进制下有多少个1
    
    int main()
    {
        int n,A[maxn];
        char s[1000];
        while (scanf("%d",&n)==1&&n) {//读入多组数据
            for (int i=0;i<n;i++) {
                scanf("%s",s);//输入字符串
                A[i]=0;
                for (int j=0;s[j]!='';j++)
                A[i]^=(1<<(s[j]-'A'));//计算每一串的<=26位二进制值
            }
            table.clear();//清空table映射
            int n1=n/2,n2=n-n1;//将待测数据分成两部分
            
            //接下来循环计算2^(n/2)个属于前半部分的子集
            for (int i=0;i<(1<<n1);i++) {
                int x=0;
                for (int j=0;j<n1;j++)
                if (i&(1<<j)) x^=A[j];
                if (!table.count(x)||bitcount(table[x])<bitcount(i))
                table[x]=i;
            }//取每个计算结果中的最大值
    
            //最后处理后半部分
            int ans=0;
            for (int i=0;i<(1<<n2);i++) {
                int x=0;
                for (int j=0;j<n2;j++)
                if (i&(1<<j)) x^=A[n1+j];
                if (table.count(x)&&bitcount(ans)<bitcount(table[x])+bitcount(i))
                ans=(i<<n1)^table[x];
            }//每次计算前查找映射中是否出现过
            printf("%d
    ",bitcount(ans));
            for (int i=0;i<n;i++)
            if (ans&(1<<i)) printf("%d ",i+1);
            printf("
    ");//输出部分
        }
        return 0;
    }
    View Code

     

    三十五、

    左偏树(可并堆)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=101000;
    struct leftist{
        int l,r,k,f,d;
    }h[N];
    int n,m;
    
    int merge(int u,int v)
    {
        if (!u||!v)
        return u+v;
        if (h[u].k>h[v].k||(h[u].k==h[v].k&&u>v))
        swap(u,v);
        int &ul=h[u].l,&ur=h[u].r;
        ur=merge(ur,v);
        h[ur].f=u;
        if (h[ul].d<h[ur].d)
        swap(ul,ur);
        h[u].d=h[ur].d+1;
        return u;
    }
    
    void erase(int u)
    {
        int ul=h[u].l,ur=h[u].r;
        h[u].k=-1;
        h[ul].f=0;
        h[ur].f=0;
        merge(ul,ur);
    }
    
    int find(int x)
    {
        return h[x].f?find(h[x].f):x;
    }
    
    int main()
    {
        cin>>n>>m;
        h[0].d=-1;
        for (int i=1;i<=n;i++)
        scanf("%d",&h[i].k);
        for (int i=1;i<=m;i++) {
            int opt,x,y;
            scanf("%d%d",&opt,&x);
            if (opt==1) {
                scanf("%d",&y);
                if (h[x].k!=-1 && h[y].k!=-1) {
                    int p=find(x),q=find(y);
                    if (p!=q)
                    merge(p,q);
                }
            }
            else if (opt==2) {
                if (h[x].k==-1)
                printf("-1
    ");
                else {
                    int p=find(x);
                    printf("%d
    ",h[p].k);
                    erase(p);
                }
            }
        }
        return 0;
    }
    View Code

    三十六

    分块(小b的询问)

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=50010,S=250;
    int n,m,q,a[N],s[S][S];
    int f[S][N],block,num;
    int belong[N],l[S],r[S],tmp[N];
    
    void build()
    {
        block=sqrt(n);
        num=n/block;
        if (n%block) num++;
        for (int i=1;i<=num;i++)
        l[i]=(i-1)*block+1,r[i]=i*block;
        r[num]=n;
        for (int i=1;i<=n;i++)
        belong[i]=(i-1)/block+1;
        for (int i=1;i<=num;i++) {
            for (int j=1;j<=n;j++)
            f[i][a[j]]=f[i-1][a[j]];
            for (int j=l[i];j<=r[i];j++)
            f[i][a[j]]++;
        }
        for (int i=1;i<=num;i++)
        for (int j=i;j<=num;j++) {
            s[i][j]=s[i][j-1];
            for (int k=l[j];k<=r[j];k++) {
                int p=f[j-1][a[k]]-f[i-1][a[k]];
                s[i][j]+=2*(p+tmp[a[k]])+1;
                tmp[a[k]]++;
            }
            for (int k=l[j];k<=r[j];k++)
            tmp[a[k]]=0;
        }
    }
    
    long long ask(int ls,int rs)
    {
        long long ans=0;
        if (belong[ls]==belong[rs]) {
            for (int i=ls;i<=rs;i++) {
                ans+=2*tmp[a[i]]+1;
                tmp[a[i]]++;
            }
            for (int i=ls;i<=rs;i++) tmp[a[i]]=0;
            return ans;
        }
        for (int i=ls;i<=r[belong[ls]];i++) {
            int p=f[belong[rs]-1][a[i]]-f[belong[ls]][a[i]];
            ans+=2*(p+tmp[a[i]])+1;
            tmp[a[i]]++;
        }
        for (int i=l[belong[rs]];i<=rs;i++) {
            int p=f[belong[rs]-1][a[i]]-f[belong[ls]][a[i]];
            ans+=2*(p+tmp[a[i]])+1;
            tmp[a[i]]++;
        }
        for (int i=ls;i<=r[belong[ls]];i++) tmp[a[i]]=0;
        for (int i=l[belong[rs]];i<=rs;i++) tmp[a[i]]=0;
        if (belong[ls]+1==belong[rs]) return ans;
        return ans+s[belong[ls]+1][belong[rs]-1];
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
        cin>>n>>m>>q;
        for (int i=1;i<=n;i++)
        cin>>a[i];
        build();
        while (m--) {
            int ls,rs;
            cin>>ls>>rs;
            cout<<ask(ls,rs)<<endl;
        }
        return 0;
    }
    View Code

    三十七

    莫队(小z的袜子)

    #include <bits/stdc++.h>
    using namespace std;
    
    int id[50005];
    const int N=50005;
    struct Mo {
        int x,y,num;
        bool operator < (const Mo &a) const {
            if (id[x]==id[a.x])
            return (id[x]&1)?y<a.y:y>a.y;
            return x<a.x;
        }
    }q[N];
    int n,m,c[N],len,l=1,r;
    unsigned int cnt[N],ans[N][2],g,k,now;
    
    long long gcd(long long a,long long b)
    {
        while (b^=a^=b^=a%=b);return a;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        for (int i=1;i<=n;i++) cin>>c[i];
        len=sqrt(n);
        for (int i=1;i<=m;i++)
        cin>>q[i].x>>q[i].y,q[i].num=i,id[i]=i/len+1;
        sort(q+1,q+1+m);
        for (int i=1;i<=m;i++) {
            if (q[i].x==q[i].y) continue;
            while (l<q[i].x) {
                --cnt[c[l]];now-=cnt[c[l]];++l;
            }
            while (l>q[i].x) {
                --l;now+=cnt[c[l]];++cnt[c[l]];
            }
            while (r<q[i].y) {
                ++r;now+=cnt[c[r]];++cnt[c[r]];
            }
            while (r>q[i].y) {
                --cnt[c[r]];now-=cnt[c[r]];--r;
            }
            if (!now) continue;
            k=(unsigned int)(r-l+1)*(r-l);
            g=gcd(now<<1,k);
            ans[q[i].num][0]=(now<<1)/g;
            ans[q[i].num][1]=k/g;
        }
        for (int i=1;i<=m;i++)
        if (!ans[i][0]) cout<<"0/1"<<endl;
        else cout<<ans[i][0]<<"/"<<ans[i][1]<<endl;
        return 0;
    }
    View Code

    三十八

    tarjan求割点

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100010;
    bool cut[N];
    int dfn[N],low[N],dfscnt;
    int n,m,s[N*2][2],o[N],cnt,fa[N],size[N];
    
    void add(int x,int y)
    {
        s[++cnt][0]=y;s[cnt][1]=o[x];o[x]=cnt;
    }
    
    void tarjan(int x,int fa)
    {
        int i=o[x];dfn[x]=low[x]=++dfscnt;
        while (i!=-1) {
            if (!dfn[s[i][0]]) {
                size[x]++;tarjan(s[i][0],x);
                if (low[s[i][0]]>=dfn[x]) cut[x]=1;
                else low[x]=min(low[x],low[s[i][0]]);
            }
            else if (s[i][0]!=fa)
            low[x]=min(low[x],dfn[s[i][0]]);
            i=s[i][1];
        }
        if (size[x]==1&&!fa) cut[x]=0;
    }
    
    int main()
    {
        int ans=0;
        ios::sync_with_stdio(false);
        cin>>n>>m;int x,y;
        memset(o,-1,sizeof(o));
        for (int i=1;i<=m;i++) {
            cin>>x>>y;add(x,y);add(y,x);
        }
        for (int i=1;i<=n;i++)
        if (!dfn[i]) tarjan(i,0);
        for (int i=1;i<=n;i++) if (cut[i]) ans++;
        cout<<ans<<endl;
        for (int i=1;i<=n;i++)
        if (cut[i]) cout<<i<<' ';cout<<endl;
        return 0;
    }
    View Code

    三十九、

    凸包(扫描法)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=10010;
    struct node {
        double x,y;
    }p[N],s[N];
    int top,n;
    
    bool cmp(node a,node b)
    {
        double A=atan2(a.y-p[1].y,a.x-p[1].x);
        double B=atan2(b.y-p[1].y,b.x-p[1].x);
        return A==B?a.x<b.x:A<B;
    }
    
    double cross(node a,node b,node c)
    {
        return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
    }
    
    double dis(node a,node b)
    {
        return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
    }
    
    int main()
    {
        cin>>n;
        for (int i=1;i<=n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
        p[0].x=p[0].y=999999999;
        int k;
        for (int i=1;i<=n;++i)
        if (p[0].y>p[i].y||(p[0].y==p[i].y&&p[0].x>p[i].x))
        p[0]=p[i],k=i;
        swap(p[k],p[1]);sort(&p[2],&p[n+1],cmp);
        s[0]=p[1],s[1]=p[2],top=1;
        for (int i=3;i<=n;) {
            if (top&&cross(s[top-1],p[i],s[top])>=0)
            --top;
            else s[++top]=p[i++];
        }
        double ans=0;
        if (top==0) ans=0;
        else if (top==1) ans=dis(s[0],s[1]);
        else {
            s[++top]=s[0];
            for (int i=0;i<top;++i) ans+=dis(s[i],s[i+1]);
        }
        printf("%.2lf
    ",ans);
        return 0;
    }
    View Code

    四十、

    2-sat(tarjan)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=2000010;
    bool flag=1;
    int n,m,scc,dfscnt;
    int s[N<<1][2],o[N];
    int low[N],dfn[N],sccno[N];
    stack <int> sta;
    
    void read(int &aa)
    {
        aa=0;char c=getchar();
        while (c>'9'||c<'0') c=getchar();
        while (c>='0'&&c<='9')
            aa=(aa<<3)+(aa<<1)+(c^48),c=getchar();
    }
    
    void add(int x,int y)
    {
        s[++o[0]][0]=y,s[o[0]][1]=o[x],o[x]=o[0];
    }
    
    void tarjan(int x)
    {
        low[x]=dfn[x]=++dfscnt;
        sta.push(x);
        for (int i=o[x];i;i=s[i][1]) {
            int y=s[i][0];
            if (!dfn[y])
                tarjan(y),low[x]=min(low[x],low[y]);
            else if (!sccno[y])
                low[x]=min(low[x],dfn[y]);
        }
        if (dfn[x]==low[x]) {
            ++scc;
            while (1) {
                int y=sta.top();
                sta.pop();
                sccno[y]=scc;
                if (x==y) break;
            }
        }
    }
    
    int main()
    {
        read(n),read(m);
        int a,b,aval,bval,nota,notb;
        for (int i=1;i<=m;++i) {
            read(a),read(aval),read(b),read(bval);
            nota=aval^1,notb=bval^1;
            add(a+nota*n,b+bval*n);
            add(b+notb*n,a+aval*n);
        }
        for (int i=1;i<=(n<<1);++i)
            if (!dfn[i]) tarjan(i);
        for (int i=1;i<=m;++i)
            if (sccno[i]==sccno[i+n]) {flag=0;break;}
        if (flag) {
            puts("POSSIBLE");
            for (int i=1;i<=n;++i)
                printf("%d ",sccno[i]>sccno[i+n]);
        }
        else puts("IMPOSSIBLE");
        return 0;
    }
    View Code

    未完待续。。。

  • 相关阅读:
    hdu1251 字典树trie 模板题
    SPOJ 1479 +SPOJ 666 无向树最小点覆盖 ,第二题要方案数,树形dp
    POJ 2125 最小点权覆盖集(输出方案)
    dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
    dfs序+主席树 BZOJ 2588 当然树链剖分+主席树也可以?
    最小生成树的边的概念问题!!! 最小生成树的计数 bzoj 1016
    BZOJ 2083 vector的巧用+二分
    vector的哈希值 Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) C
    codeforces Good bye 2016 E 线段树维护dp区间合并
    莫对 和分块 模板
  • 原文地址:https://www.cnblogs.com/fushao2yyj/p/8067921.html
Copyright © 2020-2023  润新知