zoukankan      html  css  js  c++  java
  • 模板大全(仅限个人能力)

    模板大全

    一·算法部分

    (一)排序部分

    1.冒泡排序

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n;
    int a[3000];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n-1;i++)
            for(int j=2;j<=n;j++)
                if(a[j-1]>a[j])swap(a[j-1],a[j]);
        for(int i=1;i<=n;i++)printf("%d ",a[i]);
    }
    View Code

    2.选择排序

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,a[100001];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=2;i<=n;i++)
        {
            for(int j=i;j>1;j--)
            {
                if(a[j]<a[j-1])
                {
                    int temp=a[j];
                    a[j]=a[j-1];
                    a[j-1]=temp;
                }
                else break;
            }    
        }
        for(int i=1;i<=n;i++)printf("%d ",a[i]);
    }
    View Code

    3.插入排序

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,a[100001];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=2;i<=n;i++)
        {
            int l=0,r=i-1;
            int g=a[i];
            while(l<=r)
            {
                int mid=(l+r)/2;
                if(a[mid]>g)r=mid-1;
                else l=mid+1;
            }
            for(int j=i-1;j>=l;j--)a[j+1]=a[j];
            a[l]=g;
        }
        for(int i=1;i<=n;i++)printf("%d ",a[i]);
    }
    View Code

    4.归并排序

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,a[100001];
    void up(int l,int mid,int r)
    {
        int i=l,num[100001],tot=0,j=mid+1;
        while(i<=mid&&j<=r)
        {
            if(a[i]>a[j])num[++tot]=a[j++];
            else num[++tot]=a[i++];
        }
        while(i<=mid)num[++tot]=a[i++];
        while(j<=r)num[++tot]=a[j++];
        for(int i=1;i<=tot;i++)
        {
            a[l++]=num[i];
        }
    }
    void sep(int l,int r)
    {
        if(l==r)return ;
        int mid=l+(r-l)/2;
        sep(l,mid);
        sep(mid+1,r);
        up(l,mid,r);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sep(1,n);
        for(int i=1;i<=n;i++)printf("%d ",a[i]);
    } 
    View Code

    5.快速排序(sort)

    (二)快速幂

    #include<bits/stdc++.h>
    using namespace std;
    long long b,p,k;
    long long ans,bas;
    int main()
    {
        ans=1;
        cin>>b>>p>>k;
        int t=p;
        bas=b;
        while(p!=0)
        {
            if(p & 1 ==1)ans=((ans%k)*(bas%k))%k;
            bas=((bas%k)*(bas%k))%k;
            p >>= 1;
        }
        cout<<b<<"^"<<t<<" mod "<<k<<"="<<ans%k;
    }
    View Code

    (三)三分

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int n;
    double l,r;
    double a[14];
    double calc(double a,double b)
    {
        double sum=1;
        for(int i=1;i<=b;i++)sum*=a;
        return sum;
    }
    int main()
    {
        scanf("%d%lf%lf",&n,&l,&r);
        for(int i=n;i>=0;i--)scanf("%lf",&a[i]);
        while(l+0.000001<=r)
        {
               double lmid=(l+r)/2; 
            double rmid=(lmid+r)/2;
            double sum1=0,sum2=0;
            for(int i=n;i>=1;i--)sum1+=a[i]*calc(lmid,i),sum2+=a[i]*calc(rmid,i);
            sum1+=a[0];sum2+=a[0];
    //        printf("
    f(%lf)=%lf  f(%lf)=%lf 
    ",lmid,sum1,rmid,sum2);
            sum1>sum2?r=rmid:l=lmid;
        }
        printf("%.5lf",l);
    }
    View Code

    (四)ST表

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int a[100010];
    int f[100010][60];
    int n,m;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            f[i][0]=a[i];
        }
        int LC=floor(log(n)/log(2.0));
        for(int j=1;j<=LC;++j)
        {
            for(int i=1;i<=n-(1<<j)+1;++i)
            {
                f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
            }
        }
        for(int i=1;i<=m;i++)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            int p=floor(log(r-l+1)/log(2));
            printf("%d
    ",max(f[l][p],f[r-(1<<p)+1][p]));
        }
        return 0;
    }
    View Code

    (五)字符串相关

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    char s[11100000];
    char new_s[11100000<<1];
    int f[11100000<<1];
    int ans;
    int Init()
    {
        new_s[0]='$';
        int k=1;
        int p=strlen(s);
        for(int i=0;i<p;i++)
        {
            new_s[k++]=s[i];
            new_s[k++]='#';
        }
        new_s[k]='';
        return k;
    }
    int main()
    {
        scanf("%s",s);
        int len=Init();
        int id=0,mx=0;
        for(int i=1;i<len;i++)
        {
            f[i]=mx>i?min(f[2*id-i],mx-i):1;
            while(new_s[i+f[i]]==new_s[i-f[i]])f[i]++;
            if(i+f[i]>mx)mx=i+f[i],id=i;
            ans=max(ans,f[i]);
        }
        printf("%d",ans-1);
    //    for(int i=1;new_s[i]!='';i++)cout<<new_s[i]<<" ";cout<<endl;
    //    for(int i=1;new_s[i]!='';i++)cout<<f[i]<<" ";
    }
    manacher算法
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    #define N int(1e6+2)
    #define M int(1e6+2)
    int n,m,ans,nx[N];
    char S[N],T[M];
    void getnx()
    {
        nx[0]=nx[1]=0;
        for(int i=2;i<=n;i++)
        {
            int p=nx[i-1];
            while(p&&S[i]!=S[p+1])p=nx[p];
            if(S[i]==S[p+1])nx[i]=p+1;
            else nx[i]=0;
        }
    }
    int main()
    {
        scanf("%s",T+1);
        scanf("%s",S+1);
        m=strlen(T+1),n=strlen(S+1);
        getnx();
        int p=0;
        for(int i=1;i<=m;i++)
        {
            while(p&&T[i]!=S[p+1])p=nx[p];
            if(T[i]==S[p+1])++p;
            else p=0;
            if(p==n)printf("%d
    ",i-n+1),p=nx[p];
        }
        for(int i=1;i<=n;i++)printf("%d ",nx[i]);
        return 0;
    }
    kmp字符串匹配
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ull unsigned long long
    using namespace std;
    const ull base=233;
    ull pw[100005],hs[100005];
    char S[100005];
    int n;
    void init()
    {    pw[0]=1;
        for(int i=1;i<=n;i++)pw[i]=pw[i-1]*base;
        hs[0]=0;
        for(int i=1;i<=n;i++)hs[i]=hs[i-1]*base+S[i];
    }
    inline ull geths(int l,int r)
    {    return hs[r]-hs[l-1]*pw[r-l+1];
    }
    int main()
    {    return 0;
    }
    字符串hash

    (六)网络流

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    int edge[1011][1011];
    int cx[1001],cy[1001];
    bool vis[1011];
    int n,m,e,ans;
    int path(int u)
    {
        for(int v=0;v<=m;v++)
        {
            if(edge[u][v]&&!vis[v])
            {
                vis[v]=1;
                if(cy[v]==-1||path(cy[v]))
                {
                    cx[u]=v;
                    cy[v]=u;
                    return 1;    
                }
            }
        }
        return 0;
    }
    int main()
    {
        memset(cx,-1,sizeof(cx));
        memset(cy,-1,sizeof(cy));
        scanf("%d%d%d",&n,&m,&e);
        int x,y;
        for(int i=1;i<=e;++i)scanf("%d%d",&x,&y),edge[x][y]=1;
        for(int i=1;i<=n;i++)
        {
            if(cx[i]==-1)
            {
                memset(vis,0,sizeof(vis));
                ans+=path(i);
            }
        }
        printf("%d",ans);
    }
    二分图匹配匈牙利
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int inf=1e9;
    
    int n,m,x,y,z,maxflow,deep[500];//deep深度 
    struct Edge{
        int next,to,dis;
    }edge[500];
    int num_edge=-1,head[500],cur[500];//cur用于复制head 
    queue <int> q;
    
    void add_edge(int from,int to,int dis,bool flag)
    {
        edge[++num_edge].next=head[from];
        edge[num_edge].to=to;
        if (flag) edge[num_edge].dis=dis;//反图的边权为 0
        head[from]=num_edge;
    }
    
    //bfs用来分层 
    bool bfs(int s,int t)
    {
        memset(deep,0x7f,sizeof(deep));
        while (!q.empty()) q.pop();
        for (int i=1; i<=n; i++) cur[i]=head[i];
        deep[s]=0;
        q.push(s);
    
        while (!q.empty())
        {
            int now=q.front(); q.pop();
            for (int i=head[now]; i!=-1; i=edge[i].next)
            {
                if (deep[edge[i].to]>inf && edge[i].dis)//dis在此处用来做标记 是正图还是返图 
                {
                    deep[edge[i].to]=deep[now]+1;
                    q.push(edge[i].to);
                }
            }
        }
        if (deep[t]<inf) return true;
        else return false;
    }
    
    //dfs找增加的流的量 
    int dfs(int now,int t,int limit)//limit为源点到这个点的路径上的最小边权 
    {
        if (!limit || now==t) return limit;
    
        int flow=0,f;
        for (int i=cur[now]; i!=-1; i=edge[i].next)
        {
            cur[now]=i;
            if (deep[edge[i].to]==deep[now]+1 && (f=dfs(edge[i].to,t,min(limit,edge[i].dis))))
            {
                flow+=f;
                limit-=f;
                edge[i].dis-=f;
                edge[i^1].dis+=f;
                if (!limit) break;
            }
        }
        return flow;
    }
    
    void Dinic(int s,int t)
    {
        while (bfs(s,t))
            maxflow+=dfs(s,t,inf);
    }
    
    int main()
    {
    //  for (int i=0; i<=500; i++) edge[i].next=-1;
        memset(head,-1,sizeof(head));
        scanf("%d%d",&m,&n);
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add_edge(x,y,z,1); add_edge(y,x,z,0);
        }
        Dinic(1,n);
        printf("%d",maxflow);
        return 0;
    }
    网络最大流

    (七)树图相关

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int maxn=5e5+4;
    int n,m,s;
    int head[maxn],tot;
    int d[maxn],p[maxn][21];
    struct ahah{
        int nxt,to;
    }edge[maxn<<1];
    void add(int u,int v)
    {
        edge[++tot].nxt=head[u];edge[tot].to=v;head[u]=tot;
    }
    void dfs(int u,int fa)
    {
        d[u]=d[fa]+1;p[u][0]=fa;
        for(int i=1;(1<<i)<=d[u];i++)
            p[u][i]=p[p[u][i-1]][i-1];
            for(int i=head[u];i;i=edge[i].nxt)
            {
                int v=edge[i].to;
                if(v!=fa)dfs(v,u);
            }
    }
    int lca(int a,int b)
    {
        if(d[a]>d[b])swap(a,b);
        for(int i=20;i>=0;i--)
            if(d[a]<=d[b]-(1<<i))b=p[b][i];
        if(a==b)return a;
        for(int i=20;i>=0;i--)
        {
            if(p[a][i]==p[b][i])continue;
            else a=p[a][i],b=p[b][i];
        }
        return p[a][0];
    }
    int main()
    {
        int x,y;
        scanf("%d%d%d",&n,&m,&s);
        for(int i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
        dfs(s,0);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
    }
    倍增LCA
    #include<iostream>
    #include <cstdio>
    #include <stack>
    using namespace std;
    #define N 10000
    int n,m;
    struct ahah
    {
        int nxt,to;
    } edge[N];
    int head[N],tot;
    void add(int x,int y)
    {
        edge[++tot].nxt=head[x],edge[tot].to=y;
        head[x]=tot;
    }
    int index,dfn[N],low[N];
    stack <int> S;
    bool in[N];
    int belong[N],cnt;
    void tarjan(int u)
    {
        dfn[u]=low[u]=++index;
        in[u]=1;
        S.push(u) ;
        for(int i=head[u]; i; i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                if(low[v]<low[u])low[u]=low[v];
            }
            else if(in[v]&&dfn[v]<low[u])low[u]=dfn[v];
        }
        if(dfn[u]==low[u])
        {
            ++cnt;
            int p;
            do
            {
                p=S.top();
                S.pop() ;
                in[p]=0;
                belong[p]=cnt;
            }
            while(p!=u);
        }
    }
    int main()
    {
        int x,y;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=m; i++)scanf("%d%d",&x,&y),add(x,y);
        for(int i=1; i<=n; i++)if(!dfn[i])tarjan(i);
        for(int i=1; i<=n; i++)printf("%d:%d ",i,belong[i]);
    }
    tarjan缩点
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int maxn=1e6+10;
    const int maxm=2*maxn;
    struct Edge
    {
        int u,v,w;
    } edge[maxm];
    int head[maxn],cnt;
    inline void add(int u,int v,int w)
    {
        edge[++cnt].u=head[u],edge[cnt].v=v,edge[cnt].w=w,head[u]=cnt;
    }
    int dis[maxn],vis[maxn];
    queue<int>q;
    int n,m;
    inline void spfa(int s)
    {
        for(int i=0;i<maxn;i++){
            dis[i]=2147483647;
        }
        memset(vis,0,sizeof(vis));
        dis[s]=0,vis[s]=1,q.push(s);
        while(!q.empty())
        {
            int cur=q.front();
            q.pop(),vis[cur]=0;
            for(int i=head[cur]; i; i=edge[i].u)
            {
                int v=edge[i].v;
                if(dis[v]>dis[cur]+edge[i].w)
                {
                    dis[v]=dis[cur]+edge[i].w;
                    if(!vis[v])vis[v]=1,q.push(v);
                }
            }
        }
        for(int i=1; i<=n; i++) printf("%d ",dis[i]);
    }
    int main()
    {
        int u,v,w,s;
        scanf("%d%d%d",&n,&m,&s);
        while(m--)scanf("%d%d%d",&u,&v,&w),add(u,v,w);
        spfa(s);
        return 0;
    }
    单源最短路
    #include<bits/stdc++.h>
    using namespace std;
    int m,n,k,fa[5001],xixi[2001],ans,sum;
    struct ahah
    {
        int nxt,to,w;
    } lol[200001];
    bool cmp(ahah a,ahah b)
    {
        return a.w<b.w;
    }
    int find(int x)
    {
        if(fa[x]==x)return x;
        else return fa[x]=find(fa[x]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int x,y,z;
        for(int i=1; i<=n; i++)fa[i]=i;
        for(int i=1; i<=m; i++)
        {
            cin>>x>>y>>z;
            lol[i].nxt=x;
            lol[i].to=y;
            lol[i].w=z;
        }
        sort(lol,lol+1+m,cmp);
        for(int i=1; i<=m; i++)
        {
            int g=find(lol[i].nxt);
            int h=find(lol[i].to);
            if(g!=h)
            {
                sum+=lol[i].w;
                ans++;
                if(ans==n-1)break;
                fa[g]=h;
            }
        }
        cout<<sum;
    }
    最小生成树
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    struct trie
    {   int ch[26],f,x;
    }a[200005];
    char T[100005],S[100005];
    int n,t;
    queue<int>q;
    int main()
    {   scanf("%d",&n);
        t=1;
        while(n--)
        {   scanf("%s",S+1);
            int l=strlen(S+1),p=1;
            for(int i=1;i<=l;i++)
            {   int c=S[i]-'a';
                if(!a[p].ch[c])a[p].ch[c]=++t;
                p=a[p].ch[c];
            }
            ++a[p].x;
        }
        for(int i=0;i<26;i++)
        {   if(a[1].ch[i])
            {   a[a[1].ch[i]].f=1;
                q.push(a[1].ch[i]);
            }else a[1].ch[i]=1;
        }
        while(!q.empty())
        {   int u=q.front();q.pop();
            for(int i=0;i<26;i++)
            if(a[u].ch[i])
            {   a[a[u].ch[i]].f=a[a[u].f].ch[i];
                q.push(a[u].ch[i]);
            }else a[u].ch[i]=a[a[u].f].ch[i];
        }
        return 0;
    }
    AC自动机

    二·数据结构部分

    (一)并查集

    #include<bits/stdc++.h>
    using namespace std;
    int m,n,fa[200001];
    int find(int x)
    {
        if(fa[x]==x)return x;
        else return fa[x]=find(fa[x]);
    }
    int main()
    {
        cin>>m>>n;
        for(int i=1; i<=m; i++)fa[i]=i;
        int x,y,z;
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if(x==1)
            {
                int g=find(y);
                int h=find(z);
                if(g!=h)fa[g]=h;
            }
            if(x==2)
            {
                int g=find(y);
                int h=find(z);
                if(g==h)cout<<"Y
    ";
                else cout<<"N
    ";
            }
        }
    }
    View Code

    (二)堆STL

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #define mian main
    #define N int(1e6+2)
    using namespace std;
    priority_queue <int,vector<int>,greater<int> >heap;
    int n,a[N],now;
    int f,k;
    int main()
    {
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d",&f);
            if(f==1)
            {
                scanf("%d",&k);
                heap.push(k); 
            }
            else if(f==2)printf("%d
    ",heap.top());
            else heap.pop() ;
        }
    }
    View Code

    (三)线段树

    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    long long n,m,ans,x,y,ch,val;
    struct ahah{
        long long l,r,sum,f;
    }tree[200000<<2];
    void build(int k,int l,int r)
    {
        tree[k].l=l;tree[k].r=r;
        if(tree[k].l==tree[k].r)
        {
            scanf("%lld",&tree[k].sum);
            return ;
        }
        long long mid=(tree[k].l+tree[k].r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
    }
    void update(int k)
    {
        if(tree[k].l==tree[k].r)
        {
            tree[k].sum+=y;
            return ;
        }
        long long mid=(tree[k].l+tree[k].r)>>1;
        if(x<=mid)update(k<<1);
        else update(k<<1|1);
        tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
    }
    void down(long long k)
    {
        tree[k<<1].f+=tree[k].f;
        tree[k<<1|1].f+=tree[k].f;
        tree[k<<1].sum+=(tree[k<<1].r-tree[k<<1].l+1)*tree[k].f;
        tree[k<<1|1].sum+=(tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k].f;
        tree[k].f=0;
    }
    void query(int k)
    {
        if(x<=tree[k].l&&y>=tree[k].r)
        {
            ans+=tree[k].sum;
            return ;
        }
        if(tree[k].f)down(k);
        long long mid=(tree[k].l+tree[k].r)>>1;
        if(x<=mid)query(k<<1);
        if(y>mid)query(k<<1|1);
    }
    void add(long long k)
    {
        if(tree[k].l>=x&&tree[k].r<=y)
        {
            tree[k].sum+=(tree[k].r-tree[k].l+1)*val;
            tree[k].f+=val;
            return ;
        }
        if(tree[k].f) down(k);
        long long mid=(tree[k].l+tree[k].r)>>1;
        if(x<=mid)add(k<<1);
        if(y>mid)add(k<<1|1);
        tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            ans=0;
            cin>>ch>>x>>y;
            if(ch==1)
            {
                cin>>val;
                add(1);
            }
            else
            {
                query(1);
                cout<<ans<<"
    ";
            }
        }
    }
    View Code

    (四)2B平衡树

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct tree
    {   int lc,rc,rt;
    }a[100005];
    int b[50005],cnt,t,n,m,q,x,y,z,ac;
    int ch[2000005][2],f[2000005],w[2000005],sum[2000005];
    inline int getwh(int u){return ch[f[u]][0]==u?0:1;}
    inline void rotate(int u)
    {   int fa=f[u],gr=f[fa],wh=getwh(u);
        f[u]=gr;
        ch[gr][getwh(fa)]=u;
        f[ch[u][wh^1]]=fa;
        ch[fa][wh]=ch[u][wh^1];
        f[fa]=u;
        ch[u][wh^1]=fa;
        sum[fa]=sum[ch[fa][0]]+sum[ch[fa][1]]+1;
        sum[u]=sum[ch[u][0]]+sum[ch[u][1]]+1;
    }
    inline void splay(int &root,int u)
    {   while(f[u])
        {   if(f[f[u]])
            {   if(getwh(u)==getwh(f[u]))rotate(f[u]);
                    else rotate(u);
            }
            rotate(u);
        }
        root=u;
        f[u]=0;
    }
    inline void ins(int &root,int x)
    {   int last,now=root;
        while(now)
        {   last=now;
            ++sum[last];
            if(x<=w[now])now=ch[now][0];
                else now=ch[now][1];
        }
        ch[last][x<=w[last]?0:1]=++t;
        f[t]=last;
        w[t]=x;
        sum[t]=1;
        ch[t][0]=ch[t][1]=0;
        splay(root,t);
    }
    inline int find(int &root,int x)
    {   int now=root;
        while(w[now]!=x)
        {   if(x<w[now])now=ch[now][0];
                else now=ch[now][1];
        }
        return now;
    }
    inline void del(int &root,int x)
    {   splay(root,find(root,x));
        if(ch[root][0]==0)
        {   root=ch[root][1];
            f[root]=0;
            return;
        }
        if(ch[root][1]==0)
        {   root=ch[root][0];
            f[root]=0;
            return;
        }
        int l=ch[root][0],r=ch[root][1],last;
        root=ch[root][1];
        f[root]=0;
        while(ch[r][0])sum[r]+=sum[l],r=ch[r][0];
        sum[r]+=sum[l];
        ch[r][0]=l;
        f[l]=r;
    }
    inline int getrank(int &root,int x)
    {   int ac=0,now=root;
        while(now)
        {   if(x>w[now])
            {   ac+=sum[ch[now][0]]+1;
                now=ch[now][1];
            }else now=ch[now][0];
        }
        return ac;
    }
    inline int getpre(int &root,int x)
    {   int ac=-1,now=root;
        while(now)
        {   if(w[now]<x)
            {   ac=w[now];
                now=ch[now][1];
            }else now=ch[now][0];
        }
        return ac;
    }
    inline int getnxt(int &root,int x)
    {   int ac=1e8+1,now=root;
        while(now)
        {   if(w[now]>x)
            {   ac=w[now];
                now=ch[now][0];
            }else now=ch[now][1];
        }
        return ac;
    }
    void build(int u,int l,int r)
    {   a[u].rt=++t;
        ch[t][0]=ch[t][1]=f[t]=0;
        w[t]=b[l];
        sum[t]=1;
        for(int i=l+1;i<=r;i++)ins(a[u].rt,b[i]);
        if(l==r)return;
        int mid=(l+r)>>1;
        a[u].lc=++cnt;
        build(cnt,l,mid);
        a[u].rc=++cnt;
        build(cnt,mid+1,r);
    }
    void segrank(int u,int l,int r,int ll,int rr,int w)
    {   if(l==ll&&r==rr)
        {   ac+=getrank(a[u].rt,w);
            return;
        }
        int mid=(l+r)>>1;
        if(rr<=mid)segrank(a[u].lc,l,mid,ll,rr,w);
        else if(ll>mid)segrank(a[u].rc,mid+1,r,ll,rr,w);
        else
        {   segrank(a[u].lc,l,mid,ll,mid,w);
            segrank(a[u].rc,mid+1,r,mid+1,rr,w);
        }
    }
    inline int rankinlr(int w,int l,int r)
    {   ac=0;
        segrank(1,1,n,l,r,w);
        return ac+1;
    }
    void updata(int u,int l,int r,int x,int ww)
    {   if(l==r)
        {   a[u].rt=++t;
            ch[t][0]=ch[t][1]=f[t]=0;
            w[t]=ww;
            sum[t]=1;
            return;
        }
        del(a[u].rt,b[x]);
        ins(a[u].rt,ww);
        int mid=(l+r)>>1;
        if(x<=mid)updata(a[u].lc,l,mid,x,ww);
            else updata(a[u].rc,mid+1,r,x,ww);
    }
    void segpre(int u,int l,int r,int ll,int rr,int w)
    {   if(l==ll&&r==rr)
        {   ac=max(ac,getpre(a[u].rt,w));
            return;
        }
        int mid=(l+r)>>1;
        if(rr<=mid)segpre(a[u].lc,l,mid,ll,rr,w);
        else if(ll>mid)segpre(a[u].rc,mid+1,r,ll,rr,w);
        else
        {   segpre(a[u].lc,l,mid,ll,mid,w);
            segpre(a[u].rc,mid+1,r,mid+1,rr,w);
        }
    }
    void segnxt(int u,int l,int r,int ll,int rr,int w)
    {   if(l==ll&&r==rr)
        {   ac=min(ac,getnxt(a[u].rt,w));
            return;
        }
        int mid=(l+r)>>1;
        if(rr<=mid)segnxt(a[u].lc,l,mid,ll,rr,w);
        else if(ll>mid)segnxt(a[u].rc,mid+1,r,ll,rr,w);
        else
        {   segnxt(a[u].lc,l,mid,ll,mid,w);
            segnxt(a[u].rc,mid+1,r,mid+1,rr,w);
        }
    }
    int main()
    {   scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&b[i]);
        cnt=1;
        t=0;
        build(1,1,n);
        while(m--)
        {   scanf("%d%d%d",&q,&x,&y);
            if(q!=3)scanf("%d",&z);
            if(q==1)printf("%d
    ",rankinlr(z,x,y));
            if(q==2)
            {   int l=0,r=1e8+1;
                while(r-l>1)
                {   int mid=(l+r)>>1;
                    if(rankinlr(mid,x,y)<=z)l=mid;else r=mid;
                }
                printf("%d
    ",l);
            }
            if(q==3)
            {   updata(1,1,n,x,y);
                b[x]=y;
            }
            if(q==4)
            {   ac=-1;
                segpre(1,1,n,x,y,z);
                printf("%d
    ",ac);
            }
            if(q==5)
            {   ac=1e8+1;
                segnxt(1,1,n,x,y,z);
                printf("%d
    ",ac);
            }
        }
        return 0;
    }
    View Code

    (五)splay

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,a[100005];
    struct Splay
    {    int rt,f[100005],ch[100005][2],sum[100005],t;
        int build(int l,int r)
        {    int mid=(l+r)>>1;
            sum[mid]=r-l+1;
            ch[mid][0]=l<mid?build(l,mid-1):0;
            ch[mid][1]=mid<r?build(mid+1,r):0;
            f[ch[mid][0]]=f[ch[mid][1]]=mid;
            return mid;
        }
        inline int getwh(int u){return ch[f[u]][0]==u?0:1;}
        inline void rotate(int u)
        {    int fa=f[u],gr=f[fa],wh=getwh(u);
            f[u]=gr;
            ch[gr][getwh(fa)]=u;
            f[ch[u][wh^1]]=fa;
            ch[fa][wh]=ch[u][wh^1];
            f[fa]=u;
            ch[u][wh^1]=fa;
            sum[fa]=sum[ch[fa][0]]+sum[ch[fa][1]]+1;
            sum[u]=sum[ch[u][0]]+sum[ch[u][1]]+1;
        }
        inline void splay(int u,int tar)
        {    while(f[u]!=tar)
            {    if(f[f[u]]!=tar)
                {    if(getwh(u)==getwh(f[u]))rotate(f[u]);
                        else rotate(u);
                }
                rotate(u);
            }
            if(!tar)rt=u;
        }
        int findkth(int key)
        {    int o=rt;
            while(1)
            {    if(sum[ch[o][0]]+1==key)return o;
                if(key<=sum[ch[o][0]])o=ch[o][0];
                else
                {    key-=sum[ch[o][0]]+1;
                    o=ch[o][1];
                }
            }
        }
        int getrank(int key)
        {    int o=rt,ac=0;
            while(o)
            {    if(a[o]<key)
                {    ac+=sum[ch[o][0]]+1;
                    o=ch[o][1];
                }else o=ch[o][0];
            }
            return ac+1;
        }
        void merge(int x,int y)
        {    if(x==0){rt=y;return;}
            if(y==0){rt=x;return;}
            while(ch[y][0])
            {    sum[y]+=sum[x];
                y=ch[y][0];
            }
            sum[y]+=sum[x];
            ch[y][0]=x,f[x]=y;
            splay(x,0);
        }
        void ins(int w)
        {    a[++t]=w,sum[t]=1;
            if(rt==0)
            {    rt=t;
                return;
            }
            int o=rt,last;
            while(o)
            {    ++sum[last=o];
                if(w<a[o])o=ch[o][0];
                    else o=ch[o][1];
            }
            f[t]=last,ch[last][w<a[last]?0:1]=t;
            splay(t,0);
        }
        void del(int u)
        {    splay(u,0);
            f[ch[u][0]]=f[ch[u][1]]=0;
            merge(ch[u][0],ch[u][1]);
        }
    }splay;
    int main()
    {    scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        splay.rt=splay.build(1,n);
        splay.t=n;
        return 0;
    }
    View Code

    数学数论部分

    (一)筛素数

    memset(check, 0, sizeof(check));
    int tot = 0;
    for (int i = 2; i <= n; ++i)
    {
      if (!check[i])
      {
        prime[tot++] = i;
      }
      for (int j = i+i; j <= n; j += i)
      {
        check[j] = 1;
      }
    }
    埃拉托斯特尼筛法
    #include <iostream>
    #include <cstdio>
    #include <queue>
    using namespace std;
    #define N int(1e7+2)
    #define M int(5e5+2)
    #define L 2147483647
    int n,m;
    bool prime[N];
    int f[N],tot;
    int read()
    {
        int sum=0,fg=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')fg=-1;c=getchar();}
        while(c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}
        return sum*fg;
    }
    void _prime()
    {
        for(int i=1;i<=n;i++)prime[i]=1;
        prime[1]=0;
        for(int i=2;i<=n/2;i++)
        {
            if(prime[i])f[++tot]=i;
            for(int j=1;j<=tot&&f[j]*i<=n;j++)
            {
                prime[f[j]*i]=0;
                if(i%f[j]==0)break;
            }
        }
    }
    int main()
    {
        int x;
        n=read(),m=read();
        _prime();
        while(m--)
        {
            x=read();
            if(prime[x])printf("Yes
    ");
            else printf("No
    ");
        }
    }
    线性筛

    (二)组合数递推

    for(int i=1; i<=2001; i++)
    {
        f[i][0]=1,f[i][i]=1;
        for(int j=1; j<i; j++)f[i][j]=(f[i-1][j-1]+f[i-1][j])%k;
    }
    View Code

    (三)最小公约数与最大公倍数

    #include <iostream> 
    using namespace std; 
    int main() 
    { 
        int m,n,r,t; 
        cout<<"请输入两个值,求最小公倍数"<<endl; 
        cin>>m>>n; 
        int a = m;  //先把m、n保存一份 
        int b = n; 
        if(m<n) 
        { 
            t=m;  //用分号 
            m=n;  //用分号 
            n=t; 
        } 
        while((r=m%n)!=0) 
        { 
            m=n; 
            n=r; 
        } 
        cout<<"最大公约数="<< n << endl; 
        cout<<"最小公倍数="<< a * b / n << endl;  //最后这样打印 
    }
    View Code

    (四)欧几里得扩展

    #include <cstdio>
    int exgcd(int a, int b, int &x, int &y)        //非递归版 
    {
        int d;
        if (!b) x = 1, y = 0, d = a;
        else
        {
            d = exgcd(b, a % b, y, x);
            y -= (a / b) * x;
        }
        return d;
    }
    int exgcd(int a, int b, int &x, int &y)        //递归版 
    {
        int d;
        return !b ? (x = 1, y = 0, a) : (d = exgcd(b, a % b, y, x), y -= (a / b) * x, d);
    }
    int main()
    {
        int a, b, x, y;
        scanf ("%d%d", &a, &b);
        printf("%d
    ", exgcd(a, b, x, y));
        printf("%d %d
    ", x, y);
    }
    View Code

    (五)高斯消元

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const double eps=1e-8;
    int n;
    double a[111][111];
    double b[111];
    double ans[111];
    int sign(double x)
    {
        if(fabs(x)<=eps)return 0;
        if(x>0)return 1;
        return -1;
    }
    int main()
    {
    //    printf("%lf",eps);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n+1;j++)scanf("%lf",&a[i][j]);
        }
    //    cout<<n<<"
    ";
        for(int i=1;i<=n;i++)
        {
            if(fabs(a[i][i])<=eps)
            {
                printf("No Solution
    ");
                return 0;
            }
            int p=i;
            for(int j=i;j<=n;j++)
            {
                if(fabs(a[j][i])>fabs(a[p][i]))p=j;
            }
            for(int j=1;j<=n+1;j++)swap(a[i][j],a[p][j]);
    //        swap(b[i],b[p]);
            for(int j=i+1;j<=n;j++)
            {
                double ratio=a[j][i]/a[i][i];
                for(int k=1;k<=n+1;k++)a[j][k]=a[j][k]-a[i][k]*ratio;
            }
            
    //        for(int j=1;j<=n;j++)printf("%lfX1+%lfX2+%lfX3=%lf
    ",a[j][1],a[j][2],a[j][3],a[j][4]);cout<<"
    ";
        }
        for(int i=n;i>=1;i--)
        {
            for(int j=n;j>i;j--)
            {
                if(sign(a[i][j])==0)break;
                a[i][n+1]-=ans[j]*a[i][j];
            }
            ans[i]=a[i][n+1]/a[i][i];
        }
        for(int i=1;i<=n;i++)printf("%.2lf
    ",ans[i]);
    }
    View Code

    (六)卢卡斯定理

    #include <cstdio>
    #include <cctype>
    
    typedef long long LL;
    
    #define dd c=getchar()
    inline void read(LL &x)
    {
        x=0;
        char dd;
        bool f=false;
        for(; !isdigit(c); dd)if(c=='-')f=true;
        for(; isdigit(c); dd) x=(x<<1)+(x<<3)+(c^48);
        if(f)x=-x;
        return;
    }
    
    typedef long long LL;
    
    LL mod;
    
    inline LL pow(LL a,LL b)//快速幂是为了求逆元
    {
        LL ans=1;
        for(; b; b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;
        return ans;
    }
    
    LL farc[1000005];
    
    inline void prepare(LL a)
    {
        farc[0]=1;
        for(LL i=1; i<=a; ++i)farc[i]=farc[i-1]*i%mod;
    }
    
    inline LL Csmall(LL m,LL n)//C(m,n)=(n!)/(m!*(n-m)!)
    {
        if(n<m)return 0;
        return farc[n]*pow(farc[m],mod-2)%mod*pow(farc[n-m],mod-2)%mod;//费马小定理求逆元
    }
    
    /*递归形式
    inline LL C(LL m,LL n)
    {
        if(n<m) return 0;
        if(!n)  return 1;//Lucas的边界条件
        return C(m/mod,n/mod)%mod*Csmall(m%mod,n%mod)%mod;//上面证明的Lucas定理
    }
    */
    inline LL C(LL m,LL n)
    {
        LL ans=1;
        while(n&&m&&ans)
        {
            ans=(ans*Csmall(m%mod,n%mod))%mod;
            n/=mod,m/=mod;
        }
        return ans;
    }
    
    int main()
    {
        LL T;
        read(T);
        while(T--)
        {
            LL m,n;
            read(m);
            read(n);
            read(mod);
            prepare(m+n);
            printf("%lld
    ",C(n,m+n));
        }
        return 0;
    }
    View Code

    目前整理就这么多了,以后会持续更新

  • 相关阅读:
    如何进行有效沟通避免出现误会
    如何进行有效沟通
    怎样提高自己的团队合作能力
    javaScript简介
    css文本格式详解
    css简介及相关概念
    WebGL10---3D模型的加载与使用
    Canvas绘图与动画详解
    Canvas绘制时钟
    WebGL9----将canvas作为纹理,将动画作为纹理(2)
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9416506.html
Copyright © 2011-2022 走看看