zoukankan      html  css  js  c++  java
  • c模板区域[未完待续](会不定期的更新哦(有时间就更了))(已经更十一回了哦)(和一些小知识点的总结)//退役前再次更新

           ---转载请征求博主同意

        写这个博客目的就是为了记录下学过的模板方便我这焫鷄复习吧//dalao们绕道

        近期学的:

        (1)来自机房学长jjh大神教的求1~n的所有最小素因数和加上本焫鷄的批注

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>//求1~n的最小质因数
    using namespace std;
    const int MAXN=1e6+5;
    const int LIM=1e6;
    int prime[MAXN],mnp[MAXN],cnt=0;
    bool vis[MAXN];
    int main()
    {
        for(int i=2;i<=LIM;i++)
        {
            if(!vis[i])
            {
                mnp[i]=i;//最小质因数
                prime[++cnt]=i;//质因数
            }
            for(int j=1;j<=cnt;j++)
            {
                if(1LL*i*prime[j]>LIM)
                    break;
                vis[i*prime[j]]=1;//合数直接标记
                if(i%prime[j]==0)//如果i可以整除以prime[j]
                {
                    mnp[i*prime[j]]=mnp[i];//那么这个数的最小质因数就为i的最小质因数
                    break;
                }
                else //否则
                    mnp[i*prime[j]]=prime[j];//他的最小质因数就为prime[j]
            }
        }
    }
    ヾ(◍°∇°◍)ノ゙

         (2)比较简单的筛法求素数

    void shai(int x)
    {
        memset(f,1,sizeof(f));
        for(int i=2;i<=x;i++)
        {
            if(f[i])
            {
                for(int j=i+i;j<=x;j+=i)
                {
                    f[j]=false;
                }
            }
        }
        for(int i=2;i<=x;i++)
            if(f[i])
                prime[++len]=i;
    }
    ٩(๑>◡<๑)۶

         (3)反素数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define LL long long
    using namespace std;
    LL yi[15]={2,3,5,7,11,13,17,19,23,29};
    LL n;
    LL big,num;
    void dfs(LL x,int y,int limit,int z)
    {
        if(x>n)
            return;
        if(num<y)
        {
            big=x;
            num=y;
        }
        if(num==y&&big>x)
        {
            big=x;
        }
        LL temp=x;
        for(int i=1;i<=limit;i++)
        {
            temp=temp*yi[z];
            if(temp>n)
                return;
            dfs(temp,y*(i+1),i,z+1);
        }
    }
    int main()
    {
        cin>>n;
        big=0;
        num=0;
        dfs(1,1,50,0);
        cout<<big<<endl;
        return 0;
    }
    ( ̄▽ ̄)/

         (4)来个图论的基本算法Bellman-ford

    bool Bellman-ford(int st)
    {
        memset(dis,10,sizeof(dis));
        dis[st]=0;
        bool rel=0;
        for(int i=1;i<=n;i++)
        {
            rel=0;
            for(int j=1;j<=len;j++)
            {
                if(dis[a[j].x]+a[j].v<dis[a[j].y])
                {
                    dis[a[j].y]=dis[a[j].x]+a[j].v;
                    rel=1;
                }
            }
            if(!rel) return 0;
        }
        for(int i=1;i<=len;i++)
        {
            if(dis[a[i].x]+a[i].v<dis[a[i].y])
            {
                return 1;
            }
        }
        return 0; 
    }
     ̄へ ̄

         (5)SPFA

    void SPFA(int s)        
    {
        memset(dis,10,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[s]=0;vis[s]=1;q[1]=s;
        head=0;tail=1;
        while(head<tail)
        {
            int tn=q[++head];
            vis[tn]=0;
            int te=lin[tn];
            for(int j=te;j;j=a[j].next)
            {
                int tmp=a[j].y;
                if(dis[tn]+a[j].v<dis[tmp])
                {
                    dis[tmp]=dis[tn]+a[j].v;
                    if(!vis[tmp])
                    {
                        q[++tail]=tmp;
                        vis[tmp]=1;
                    }
                }
            }
        }
    }
    []~( ̄▽ ̄)~*

         (6)dijkstra算法

    void dijkstra(int st)
    {
        for(int i=1;i<=n;i++)
            dis[i]=a[st][i];
        memset(vis,0,sizeof(vis));
        vis[st]=1;dis[st]=0;
        for(int i=1;i<n;i++)
        {
            int minn=9999999;
            int k=0;
            for(int j=1;j<=n;j++)
            {
                if(!vis[j]&&dis[j]<minn)
                {
                    minn=dis[j];
                    k=j;
                }
            }
            if(k==0)
                return;
            vis[k]=1;
            for(int j=1;j<=n;j++)
            {
                if((!vis[j])&&(dis[k]+a[k][j]<dis[j]))
                    dis[j]=dis[k]+a[k][j];
            }
        }
    }
     ̄ω ̄=

         补:堆优化的Dijkstra+邻接表//听说SPFA死了....

     1 void dijkstra(int s)
     2 {
     3     priority_queue<P,vector<P>,greater<P> > q;//小根堆因为你要找最短路,若你要找最长路,那么用大根堆。
     4     memset(dis,0,sizeof(dis));
     5     dis[s]=1;
     6     memset(vis,0,sizeof(vis));
     7     q.push(make_pair(dis[s],s));
     8     while(!q.empty())
     9     {
    10         P tmp=q.top();
    11         q.pop();
    12         int x=tmp.second;
    13         if(vis[x]) continue;
    14         vis[x]=true;
    15         for(int i=lin[x],y;i;i=a[i].next)
    16         {
    17             y=a[i].y;
    18             if(dis[y]<dis[x]*a[i].v)
    19             {
    20                 dis[y]=dis[x]*a[i].v;
    21                 if(!vis[y])
    22                     q.push(make_pair(dis[y],y));//或者将dis[y]改为-dis[y],这样也就是最长路了
    23             }
    24         }
    25     }
    26 }
    (◕ᴗ◕✿)

         (7)最小生成树---Prim算法

    void Prim(int s)
    {
        memset(dis,10,sizeof(dis));
        for(int i=1;i<=n;i++)
            dis[i]=a[s][i];//所有点都不在队列里,除了s
        memset(vis,0,sizeof(vis));
        vis[s]=1; sumn=0;
        for(int i=2;i<=n;i++)
        {
            //寻找现在能到达的边中最短的那条
            int minn=a[0][0],c=0;
            for(int j=1;j<=n;j++)
            {
                if((!vis[j])&&(dis[j]<minn))
                {
                    minn=dis[j];
                    c=j;
                }
            }
            //c点到达了,最小生成树长度增加
            vis[c]=1;
            sumn+=minn;
            //基于这个点做松弛操作
            for(int j=1;j<=n;j++)
            {
                if((a[c][j]<dis[j])&&(!vis[j]))
                    dis[j]=a[c][j];
            }
        }
    }
    (。・ω・。)

          //未完待续(欲知后事如何请听下回分解)

     第二回更

          (8)先来个网络流(带上Dinic优化)

    void insert(int x,int y,int v)
    {
        a[++len].y=y; a[len].v=v; a[len].next=lin[x]; lin[x]=len; rev[len]=len+1;
        a[++len].y=x; a[len].v=0; a[len].next=lin[y]; lin[y]=len; rev[len]=len-1;
    }
    int head,tail;
    bool make_level()
    {
        head=0,tail=1;
        memset(l,-1,sizeof(l));
        q[1]=0;l[0]=0;
        while(head++<tail)
        {
            int tn=q[head];
            for(int i=lin[tn];i;i=a[i].next)
            {
                if(a[i].v&&l[a[i].y]<0)
                {
                    q[++tail]=a[i].y;
                    l[a[i].y]=l[tn]+1;
                }
            }
        }
        return l[n]>=0;
    }
    long long MAX(long long k,long long flow)
    {
        if(k==n)
            return flow;
        long long maxflow=0,d=0;
        for(int i=lin[k];i&&maxflow<flow;i=a[i].next)
        {
            if(l[a[i].y]==l[k]+1&&a[i].v)
            {
                if(d=MAX(a[i].y,min(flow-maxflow,a[i].v)))
                {
                    maxflow+=d;
                    a[i].v-=d;
                    a[rev[i]].v+=d;
                }
            }
        }
        if(!maxflow)
            l[k]=-1;
        return maxflow;
    }
    void Dinic()
    {
        long long d;
        while(make_level())
            while(d=MAX(1,INF))
                sum+=d;
    }
    (๑╹◡╹)ノ"""

          (9)最小生成树---Kruskal算法(中间有并查集的算法详细见(10))

    void Kruskal()
    {
        for(intt i=1;i<=n;i++)
            father[i]=i;
        sort(a+1,a+m+1,mycmp);
        int cal=0;
        for(int i=1;i<=len;i++)
        {
            int v=getfather(a[i].x);
            int u=getfather(a[i].y);
            if(v!=u)
            {
                father[v]=u;
                if(++cal==n-1)
                {
                    cout<<a[i].v<<endl;
                    return;
                }
            }
        }
    }
    !!!∑(゚Д゚ノ)ノ

        (10)并查集

    int getfather(int k)//找到祖先
    {
        if(father[k]==k)
            return k;
        father[k]=getfather(father[k]);
        return father[k];
    }
    void merge(int x,int y)//合并
    {
        int fx=getfather(x);
        int fy=getfather(y);
        father[fx]=fy;
    }
    bool judge(int x,int y)//判断是否在一个并查集中
    {
        int fx=getfather(x);
        int fy=getfather(y);
        return (fx==fy);
    }
    ヾ(✿゚▽゚)ノ

        (11)拓扑排序---topsort

    void topsort()
    {
        int head=0,tail=0;
        for(int i=1;i<=n;i++)
            if(!id[i])
                q[++tail]=i;
        while(head<tail)
        {
            head++;
            for(int i=1;i<=n;i++)
            {
                if(a[q[head]][i])
                {
                    id[i]--;
                    if(!id[i])
                        q[++tail]=i;
                }
            }
        }
    }
    _(:з」∠)_

        (补充)topsort(邻接表)

    void topsort()
    {
        sum[s]=1;
        int head=0,tail=0;
        for(int i=1;i<=n;i++)
            if(!id[i])
                q[++tail]=i;
        while(head<tail)
        {
            head++;
            int tn=q[head];
            for(int i=lin[tn];i;i=a[i].next)
            {
                int tmp=a[i].y;
                id[tmp]--;
                if(!id[tmp])
                    q[++tail]=tmp;
            }
        }
    }
    ٩(๑>◡<๑)۶

     第三回更

        今天就更新一下字符串的东西吧

       (12)字符串-----KMP

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 1000010
    using namespace std;
    int p[MAXN];
    int main()
    {
        string a,b;
        cin>>a>>b;
        int j=-1;
        int la=a.size(),lb=b.size();
        p[0]=-1;
        for(int i=1;i<lb;i++)
        {
            while((j>=0)&&b[i]!=b[j+1])
                j=p[j];
            if(b[j+1]==b[i])
                j++;
            p[i]=j;
        }
        j=-1;
        for(int i=0;i<la;i++)
        {
            while((j>-1)&&b[j+1]!=a[i])
                j=p[j];
            if(b[j+1]==a[i])
                j++;
            if(j==lb-1)
            {
                cout<<i-j+1<<endl;//b在a中出现的位置
                j=p[j];
            }
        }
        return 0;
    }
    对于之前KMP打错表示抱歉

           (13)字符串-----trie树

    struct node
    {
        char ch;             //本节点的值
        bool endflag;     //是否是某个单词的最后一个字符
        int link[26];         //26个分叉
    } tree[600100];
    void add(int k,int node)  //k是s的第k个字符,node为当前节点。
    {      
        int  chindex=s[k]-‘A’;  //字符的编号
        if (tree[node].link[chindex]==0)   //新开节点
        {
            tree[node].link[chindex]=++len;            
            tree[len].ch=s[k]; 
            tree[len].endflag=false;
        }
        int nexnode=tree[node].link[chindex];  //下一个节点的下标
        if (k==(int)s.size()-1)
        {
            tree[nexnode].endflag=true;
            return;
        }
        add(k+1,nexnode);    
    }
    bool find(int k, int last,int node)
    //k是要查找字符串s的第k个元素
    {
        int chindex=s[k]-'a';
        if (tree[node].link[chindex]==0)  return false;
        int nextnode=tree[node].link[chindex];
        if (k==(s.size()-1)) //如果k是最后一个字符
           if (tree[nextnode].endflag)  return true;
            else                   return false;
        return find(k+1,last,nextnode);
    }
    (▼ヘ▼#)

       (14)字符串------AC自动机

    struct node//注:fromjzyz ftp:
    {
        int endflag; //是否是某个单词的最后一个字符.小心有多个重复的单词
        int fail;  //失败指针
        int link[26]; //26个分叉
    } tree[510100];
    
    char s[1001000];  //用字符数组代替字符串,在1000000 个字符条件下,速度会快一些。
    //string s;
    int n,m,len=0,ans,slen;
    int head,tail,root=0;
    int q[510000];
    void add(int k,int node)  //k是s的第k个字符,root为当前节点。
    {      
        int  chindex=s[k]-'a';
        if (tree[node].link[chindex]==0)   //新开节点
        {
            tree[node].link[chindex]=++len;            
            tree[len].endflag=0; //因为存在有多个相同的单词
            tree[len].fail=root;
        }
        int nexnode=tree[node].link[chindex];
        if (k==slen-1)  //恰好是一个单词的结尾。
        {
            tree[nexnode].endflag++;
            return;
        }
        add(k+1,nexnode);    
    }
    void init()
    {
        scanf("%d
    ",&n);
        memset(tree,0,sizeof(tree));
        for (int i=0;i<n;i++)
        {
            scanf("%s",s);     slen=strlen(s);  //因为字符串比较多,用了c语言的字符串读入。
            add(0,root);
        }    
    }
    void buildac()//生成fail指针,建好AC自动机
    //用bfs生成一个层次序列,fail指针肯定往前跳。按层次依次求出fail指针
    {
        head=tail=0;
        q[tail]=root;
        while (head<=tail) //bfs广度优先遍历 trie树
        {        
                //if (head>300000) head=0;
                 int now=q[head++];//  当前的节点
            int temp; //用来存储临时的fail指针,是tree的下标
            for (int i=0;i<26;i++) //        
                if (tree[now].link[i])  //求link[i].fail指针                
                {
                    int nextnode=tree[now].link[i];
                    if (now!=root)//如果是根,那么fail肯定是root
                    {
                        temp=tree[now].fail;
                        while (!tree[temp].link[i] && temp)//找不到与 link[i]匹配的前缀  且没有退到根                
                            temp=tree[temp].fail; //继续向上退
                            tree[nextnode].fail=tree[temp].link[i];    
                    }
                           
                           q[++tail]=nextnode;  //让这个子节点进队。
                }                
        }
    }
    
    void find()
    {   
          ans=0;
        int now=root;
        scanf("%s",s);          len=strlen(s);  //这里用的也是c语言的字符。
        for(int i=0;i<len;i++)
        {
            int chindex=s[i]-'a';
            while( !tree[now].link[chindex] && now!=root)//如果找不到,往回返        
                now=tree[now].fail;
            now=tree[now].link[chindex];//下一层传递。
            int temp=now;//如果找到某个单词
            while(temp!=root&& tree[temp].endflag>-1 ) //如果找到某个单词,累加到结果
            {
                ans+= tree[temp].endflag;
                tree[temp].endflag=-1;
                temp=tree[temp].fail;
            }
        }
        printf("%d",ans);
    }
    
    int main()
    {
         freopen("ac.in","r",stdin);
         freopen("ac.out","w",stdout); 
         //scanf("%d",&m);
         //while (m--)
         {
            init();
            buildac();
            find(); 
         }
         fclose(stdin);fclose(stdout);
         return 0; 
    }
    ( • ̀ω•́ )✧

     第四回更

       (15)hash表  

    const int maxprime=2323237;
    const int step=7;
    struct shaodw
    {
        int v,num;
    }hash[maxprime+5];
    int n,x;
    int find(int x)
    {
        int temp=x%maxprime;
        while(hash[temp].v!=0&&hash[temp].v!=x)
        {
            temp+=step;
            if(temp>=maxprime)
                temp-=maxprime;
        }
        return temp;
    }
    void insert(int x)
    {
        int now=find(x);
        if(hash[now].v==x)
            hash[now].num++;
        else
        {
            hash[now].v=x;
            hash[now].num=1;
        }
    }
    int main()
    {
        memset(hash,0,sizeof(hash));
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>x;
            insert(x);
        }
        return 0;
    }
    ٩(๑❛ᴗ❛๑)۶

       (16)hash--字符串

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    const unsigned int seed=131;
    #define mod 2323237
    int n,len=0,lin[300n0010];
    char c[210];
    struct node{
        int ne;
        char ch[210];
    }hash[50010];
    
    unsigned int getkey(){
        int len=strlen(c);
        unsigned int key=0;
        for (int i=0;i<len;i++)
            key=key*seed+c[i];
        return (key&0x7fffffff)%mod;
    }
    
    void add(int key)
    {hash[++len].ne=lin[key];lin[key]=len;strcpy(hash[len].ch,c);}
    
    bool find(){
        int key=getkey();
        for (int i=lin[key];i;i=hash[i].ne)
            if (strcmp(hash[i].ch,c)==0)    return false;
        add(key);
        return true;
    }
    
    int main(){
        //freopen("add.in 
    
    ","r",stdin);
        scanf("%d",&n);
        for (int i=1;i<=n;i++){
            scanf("%s",c);
            if (!find())    printf("%d
    ",i);
        }
        return 0;
    }
    (╬ ̄皿 ̄)

      (17)莫队模板//例题:小Z的袜子

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    inline long long read()
    {
        long long x=0,f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    long long gcd(long long a,long long b)
    {return b==0?a:gcd(b,a%b);}
    struct shadow
    {
        long long l,r,id;
    }a[300000],S[300000];
    long long s[300000],cnt[300000];
    long long d[300000],mo[300000];
    bool mycmp(shadow x,shadow y)
    {
        if(x.l!=y.l)
            return x.l<y.l;
        return x.r<y.r;
    }
    bool cmp(shadow x,shadow y)
    {return x.r>y.r;}
    bool dmp(shadow x,shadow y)
    {return x.id<y.id;}
    long long ans=0;
    int len=0;
    void simp(long long a,long long b,long long id)
    {
        long long t=gcd(a,b);
        a/=t;b/=t;
        S[++len].l=a;
        S[len].r=b;
        S[len].id=id;
    }
    long long str(long long x)
    {return x*x;}
    int main()
    {
        //freopen("hose.in","r",stdin);
        //freopen("hose.out","w",stdout);
        long long n,m;
        n=read();m=read();
        for(int i=1;i<=n;i++)
        {
            s[i]=read();
        }
        for(int i=1;i<=m;i++)
        {
            a[i].l=read();
            a[i].r=read();
            a[i].id=i;
        }
        sort(a+1,a+1+m,mycmp);
        int qw=int(sqrt(1.0*m));
        int ii;
        for(ii=qw;ii<=m;ii+=qw)
        {
            sort(a+ii-qw+1,a+1+ii,cmp);
        }
        if(ii!=m)
            sort(a+ii+1,a+ii+m+1,cmp);
        long long l=1;
        long long r=0;
        for(int i=1;i<=m;i++)
        {
            while(r<a[i].r)
            {
                r++;
                ans-=str(cnt[s[r]]);
                cnt[s[r]]++;
                ans+=str(cnt[s[r]]);
            }
            while(r>a[i].r)
            {
                ans-=str(cnt[s[r]]);
                cnt[s[r]]--;
                ans+=str(cnt[s[r]]);
                r--;
            }
            while(l>a[i].l)
            {
                l--;
                ans-=str(cnt[s[l]]);
                cnt[s[l]]++;
                ans+=str(cnt[s[l]]);
            }
            while(l<a[i].l)
            {
                ans-=str(cnt[s[l]]);
                cnt[s[l]]--;
                ans+=str(cnt[s[l]]);
                l++;
            }
            long long M=(long long)ans-(a[i].r-a[i].l+1);
            long long N=(long long)(a[i].r-a[i].l+1)*(a[i].r-a[i].l);
            simp(M,N,a[i].id);
        }
        sort(S+1,S+1+m,dmp);
        for(int i=1;i<=m;i++)
        {
            cout<<S[i].l<<'/'<<S[i].r<<endl;
        }
        return 0;
    }
    (*@ο@*)

       (18)LCA模板

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    inline int read()
    {
        char ch=getchar();
        int x=0,f=1;
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    const int MAXN=100100;
    struct shadow
    {
        int y,next;
    }a[MAXN*4];
    int lin[MAXN*4];
    int len=0;
    void insert(int x,int y)
    {
        a[++len].next=lin[x];
        lin[x]=len;
        a[len].y=y;
    }
    int dep[MAXN*4];
    int f[MAXN*4],size[MAXN*4],son[MAXN*4],top[MAXN*4];
    void dfs1(int x)
    {
        dep[x]=dep[f[x]]+1;
        size[x]=1;
        for(int i=lin[x];i;i=a[i].next)
        {
            if(a[i].y!=f[x]&&!f[a[i].y])
            {
                f[a[i].y]=x;
                dfs1(a[i].y);
                size[x]+=size[a[i].y];
                if(size[son[x]]<size[a[i].y])
                    son[x]=a[i].y;
            }
        }
    }
    void dfs2(int x)
    {
        if(x==son[f[x]])
            top[x]=top[f[x]];
        else
            top[x]=x;
        for(int i=lin[x];i;i=a[i].next)
            if(f[a[i].y]==x)
                dfs2(a[i].y);
    }
    int ask(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]>dep[top[y]])
                x=f[top[x]];
            else
                y=f[top[y]];
        }
        if(dep[x]<dep[y])
            return x;
        else
            return y;
    }
    int main()
    {
        int n,m;
        n=read();m=read();
        for(int i=1;i<n;i++)
        {
            int x,y;
            x=read();y=read();
            insert(x,y);
            insert(y,x);
        }
        dfs1(1);
        dfs2(1);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            x=read();y=read();
            int ans=ask(x,y);
            cout<<ans<<endl;
        }
        return 0;
    }
    (๑*◡*๑)

        (19)归并排序

    int a[100002],c[100002];
    void worksort(int l,int r)
    {
        int cnt=0;//逆序对个数
        int mid,tmp,i,j;
        if(r>l+1)
        {
            mid=(l+r)/2;
            worksort(l,mid-1);
            worksort(mid,r);
            tmp=1;
            for(i=l,j=mid;i<=mid-1&&j<=r;)
            {
                if(a[i]>a[j])
                {
                    c[tmp++]=a[j];
                    cnt+=mid-i;
                }
                else
                    c[tmp++]=a[i++];
            }
            if(j<=r)
                for(;j<=r;j++)
                    c[tmp++]=a[j];
            else
                for(;i<=mid-1;i++)
                    c[tmp++]=a[i];
            for(i=l;i<=r;i++)
                a[i]=c[i];
        }
        else
        {
            if(l+1==r)
                if(a[l]>a[r])
                {
                    swap(a[l],a[r]);
                    cnt++;
                }
        }
    }
    (ノ`Д)ノ

     第五会更

       (20)trajan

    void trajan(int x)
    {
        low[x]=dfn[x]=++num;
        s.push(x);
        for(int i=lin[x];i;i=a[i].next)
        {
            int g=a[i].y;
            if(!dfn[g])
            {
                trajan(g);
                low[x]=min(low[x],low[g]);
            }
            else if(!vis[g])
                low[x]=min(low[x],dfn[g]);
        }
        if(low[x]==dfn[x])
        {
            sum++;
            while(1)
            {
                int t=s.top();
                s.pop();
                vis[t]=sum;
                if(t==x)
                    break;
            }
        }
    }
    (꒪Д꒪)ノ

       (21)今天学到了一个新东西..因为我们oj限制栈的大小,所以得用一个东西把限制的大小调大(NOIP和CCF这些正规的比赛都不会限制大小但....省选会)

        int __size__ = 20 << 20; // 20MB
        char *__p__ = (char*)malloc(__size__) + __size__;
        __asm__("movl %0, %%esp
    " :: "r"(__p__));
    (。◕ˇ∀ˇ◕)

        (22)Kosaraju算法

    void DFS_T(int u)
    {
        int i,v;
        if(used[u])return ;
        used[u]=1;id[u]=scc;
        for(i=q[u];i!=-1;i=Tedge[i].pre)
        {
            v=Tedge[i].d;
            if(!used[v])
            DFS_T(v);
        }
    }
    void DFS(int v){
        int i,u;
        if(used[v])return ;
        used[v]=1;
        for(i=p[v];i!=-1;i=edge[i].pre)
        {
            u=edge[i].d;
            if(!used[u])DFS(u);
        }
        order[++num]=v;
    }
    int Kosaraju()
    {
        int i,j,k,v,u;
        memset(used,0,sizeof(used));num=0;
        for(i=1;i<=n;++i)
            if(!used[i])
                DFS(i);
        memset(used,0,sizeof(used));
        memset(id,0,sizeof(id));scc=0;
        for(i=num;i>=1;--i)
             if(!used[order[i]])
                 scc++,DFS_T(order[i]);
    }                    
    ︿( ̄︶ ̄)︿

        第六会更

      (23)费用流模板

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<iomanip>
    using namespace std;
    const int maxn=10100;
    const int oo=202116108;  //memset 12 的值
    
    struct node
    {
        int y,v,flow,next; //v是费用,flow是流量
        int reverse;  //反向变的编号。
    }edge[5*maxn];  // 邻接表的 边数组
    int link[maxn];  //邻接表的 点数组
    int q[1000010];
    int dis[maxn],tot=0;
    int temp,ans=0;
    int n,m,s,t; //s是源点, t是汇点。
    bool vis[maxn];
    int lastnode[maxn],lastedge[maxn]; //记录增广路径用。
    void add (int x,int y,int z,int c,int re)
    {
        edge[++tot].y=y; edge[tot].v=-z; edge[tot].flow=c;
        edge[tot].reverse=tot+re;
        edge[tot].next=link[x]; link[x]=tot;
    }
    void init()
    {
        scanf("%d %d", &n,&m);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
            {
                int xx=(i-1)*m+j; //二维压一维。xx表示第i行第j列点的编号
                int yy=2*xx;  xx=yy-1;
                scanf("%d" ,&temp);
                add(xx,yy,temp,1,1);  //正向边
                add(yy,xx,-temp,0,-1); //反向边,退流的话把相关的费用返还。
                if (j<m) //当前点右方有点
                {
                    add(yy,yy+1,0,1,1); //右方连一个费用为0,流量为1的边。
                    add(yy+1,yy,0,0,-1); //逆向边的流量初值为0;
                }
                if (i<n)
                {
                    add(yy,yy+2*m-1,0,1,1); //下方的边费用也是1.
                    add(yy+2*m-1,yy,0,0,-1);
                }
                s=1; t=n*m*2-1;
                edge[s].flow=2; //源点出去的流量只为2.限制了总体流量。
            }
    }
    bool spfa()
    {
        memset(vis,0,sizeof(vis));
        memset(dis,12,sizeof(dis));
        dis[1]=0; vis[1]=true;
        q[0]=1; 
        int head=0,tail=0;
        while (head<=tail) //队列不为空
        {
            int tn=q[head++];
            for (int te=link[tn];te;te=edge[te].next)  //枚举边
            {
                int ty=edge[te].y;
                if (edge[te].flow &&(dis[tn]+edge[te].v<dis[ty]))  //首先的有流量再判断费用
                {
                    if (!vis[ty])  //不在队列里。
                    {
                        q[++tail]=ty;
                        vis[ty]=true;
                    }
                    dis[ty]=dis[tn]+edge[te].v;
                    lastnode[ty]=tn; lastedge[ty]=te;   //增广路的记录,用于下面的增广。
                }
            }
            vis[tn]=false;
        }
        return(dis[t]!=oo); //如果到t的最短距离存在,表明存在一个费用最小的增广路。
    }
    void agu()  //按照增广路径进行流量增减
    {
        int delta=oo;
        for (int now=t;now!=s;now=lastnode[now])
            if (edge[lastedge[now]].flow<delta )   //找出流量
                delta=edge[lastedge[now]].flow;
        for (int now=t;now!=s;now=lastnode[now])  //更新流量
        {
            int te=lastedge[now];
            edge[te].flow-=delta;
            int re=edge[te].reverse;
            edge[re].flow+=delta;
            ans+=delta*(-edge[te].v);        
        }
    }
    void costflow()
    {
        while (spfa())
            agu();
        cout<<ans<<endl;
    }
    int main()
    {
        freopen("message.in","r",stdin);
        freopen("message.out","w",stdout);
          init();
          costflow();
        fclose(stdin);fclose(stdout);
        return 0; 
    }
    ヽ(゚∀゚)メ(゚∀゚)ノ

        (24)输出n位小数

    cout<<setiosflags(ios::fixed)<<setprecision(n);//n为你要输出小数的位数记得加上头文件#include<iomanip>

       (25)二分图------邻接矩阵(DFS)

    bool find(int x)
    {
        for(int i=1;i<=m;i++)
        {
            if(a[x][i]&&!vis[i])
            {
                vis[i]=1;
                if(!id[i]||find(id[i]))
                {
                    id[i]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        for(int i=1;i<=n;i++)
        {
            memset(vis,0,sizeof(vis));
            bool flag=find(i);
            if(flag)
            {
                ans++;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    (๑╹◡╹)ノ"""

         //vector的一些用法

    push_back   在数组的最后添加一个数据
    pop_back    去掉数组的最后一个数据 
    at                得到编号位置的数据
    size           当前使用数据的大小
    erase         删除指针指向的数据项
    clear          清空当前的vector
    empty        判断vector是否为空
    swap         与另一个vector交换数据
    begin         返回第一个元素
    end            返回最后一个元素
    //头文件  #include<vector>

         //位运算一些基本技巧

     1 x&y   表示在x和y的二进制中如果同位上x和y的数都为一则为一否则为0;如下
     2             10010110
     3         &   01011010
     4 -------------------------
     5             00010010
     6 x|y  表示在x和y的二进制中如果同为上的x和y的数有一个为一的话那么就为一否则为0,如下:
     7             1011011
     8         |   0110001
     9 ------------------------
    10             1111011
    11 x^y(异或) 表示x和y的二进制中如果同位上一个为1,一个为0那么为1,都为1或都为0则为0 如下:
    12             1100101
    13          ^  0111011
    14 -------------------------
    15             1011110
    16 ~x 则表示把x二进制中所有为0变1,1变0,取反的时候是无符号的

         (27)dfs序递归版

    void dfs(int now,int father)
    {
        l[now]=++cnt;
        for(int i=linkk[now];i;i=e[i].next)
        {
            int tn=e[i].y;
            if(tn==father)
                continue;
            dfs(tn,now);
        }
        r[now]=cnt;
    }
    ✧(≖ ◡ ≖✿

        (28)dfs序非递归版

    void Shadow()
    {
        memset(id,0,sizeof(id));
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        for(int i=1;i<=n;i++)
            id[i]=linkk[i];
        stack[++top]=1,stack[0]=0;
        while(top)
        {
            int now=stack[top];
            if(!l[now])
                l[now]=++cnt,dep[now]=dep[stack[top-1]]+1,v[now]=v[stack[top-1]]+v[now];
            if(id[now])
            {
                int edgee=id[now];
                id[now]=e[edgee].next;
                if(e[edgee].y==stack[top-1])
                    continue;
                stack[++top]=e[edgee].y;
            }
            else
                r[stack[top--]]=cnt;
        }
    }
    \\٩('ω')و////

        (29)树链剖分+线段树(ojP2047,soj375)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 101000
    using namespace std;
    inline int read()
    {
        char ch=getchar();
        int x=0,f=1;
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    struct shadow
    {
        int y,next;
    }a[MAXN*2];
    int d[MAXN][3];
    int n,len=0,lin[MAXN*2];
    void insert(int x,int y)
    {
        a[++len].y=y;
        a[len].next=lin[x];
        lin[x]=len;
    }
    int siz[MAXN],top[MAXN],fa[MAXN],w[MAXN];
    int son[MAXN],tree[MAXN],dep[MAXN],num=0;
    void dfs(int x)
    {
        siz[x]=1;son[x]=0;
        for(int i=lin[x];i;i=a[i].next)
        {
            int tmp=a[i].y;
            if(tmp!=fa[x])
            {
                fa[tmp]=x;
                dep[tmp]=dep[x]+1;
                dfs(tmp);
                if(siz[tmp]>siz[son[x]])
                    son[x]=tmp;
                siz[x]+=siz[tmp];
            }
        }
    }
    void build(int x,int y)
    {
        w[x]=++num; top[x]=y;
        if(son[x]) 
            build(son[x],top[x]);
        for(int i=lin[x];i;i=a[i].next)
        {
            int tmp=a[i].y;
            if(tmp!=son[x] &&tmp!=fa[x])
                build(tmp,tmp);
        }
    }
    void updata(int root,int lo,int hi,int g,int x)
    {
        if(g>hi||lo>g) return;
        if(lo==hi)
        {
            tree[root]=x;
            return ;    
        }
        int mid=(hi+lo)/2,ls=root<<1,rs=root<<1|1;
        updata(ls,lo,mid,g,x);
        updata(rs,mid+1,hi,g,x);
        tree[root]=max(tree[ls],tree[rs]);
    }
    int search(int root,int lo,int hi,int l,int r)
    {
        if(l>hi||r<lo) return 0;
        if(l<=lo&&hi<=r)
            return tree[root];
        int mid=(lo+hi)/2,ls=root<<1,rs=root<<1|1;
        int templ=search(ls,lo,mid,l,r);
        int tempr=search(rs,mid+1,hi,l,r);
        return max(templ,tempr);
    }
    inline int find(int x,int y)
    {
        int f1=top[x],f2=top[y],tmp=0;
        while(f1!=f2)
        {
            if(dep[f1]<dep[f2])
                swap(f1,f2),swap(x,y);
            tmp=max(tmp,search(1,1,num,w[f1],w[x]));
            x=fa[f1];f1=top[x];
        }
        if(x==y) return tmp;
        if(dep[x]>dep[y]) swap(x,y);
        return max(tmp,search(1,1,num,w[son[x]],w[y]));
    }
    char ch[MAXN];
    inline void r()
    {
        ch[0]=' ';
        while(ch[0]<'C'||ch[0]>'Q')
            scanf("%s",ch);
    }
    int main()
    {
        int __size__ = 20 << 20; // 20MB
     char *__p__ = (char*)malloc(__size__) + __size__;
     __asm__("movl %0, %%esp
    " :: "r"(__p__));
        int t=read();
        for(int i=1;i<=t;i++)
        {
            memset(siz,0,sizeof(siz));
            memset(lin,0,sizeof(lin));
            memset(tree,0,sizeof(tree));
            n=read();
            int oo=(n+1)/2;
            for(int j=1;j<n;j++)
            {
                int x=read(),y=read(),z=read();
                d[j][0]=x;d[j][1]=y;d[j][2]=z;
                insert(x,y);insert(y,x);
            }
            dfs(oo);
            build(oo,oo);
            for(int i=1;i<n;i++)
            {
                if(dep[d[i][0]]>dep[d[i][1]])
                    swap(d[i][0],d[i][1]);
                updata(1,1,num,w[d[i][1]],d[i][2]);
            }
            for(r();ch[0]!='D';r())
            {
                int q=read(),h=read();
                if(ch[0]=='Q')
                    cout<<find(q,h)<<endl;
                else
                    updata(1,1,num,w[d[q][1]],h);
            }
        }
        return 0;
    }
    (o°ω°o)

                //连个stl全排序的函数

    next_permutation(a+1,a+1+n);//排1,2,3,4....n
    prev_permutation(a+1,a+1+n);//排n-1,n-2,n-3.....1

        (30)next_premutation的代码实现

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int a[100000];
    int main()
    {
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        for(int i=1;i<=m;i++)//一共调整m次
        {//以下为核心代码
            int j,k,p,q,temp;
            j=n-1;
            while((j>0)&&(a[j]>a[j+1])) 
                j--;
            if(j>0)
            {
                k=n;
                while(a[k]<a[j])
                    k--;
                swap(a[j],a[k]);
                for(p=j+1,q=n;p<q;p++,q--)
                    swap(a[p],a[q]);
            }
        }
        for(int i=1;i<=n;i++)
            cout<<a[i]<<' ';
        cout<<endl;
        return 0;
    }
    ꒰╬•᷅д•᷄╬꒱

         (31)[noip2006普及]Jam的计数法(解此类问题的代码,由上一组合产生下一组合)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    char ch[26];
    int main()
    {
        int l,r,w;
        cin>>l>>r>>w;
        cin>>ch;
        r=r+'a'-1;
        for(int i=1;i<=5;i++)
        {
            int j=w-1;
            while((j>=0)&&(ch[j]==r-(w-1-j))) j--;
            if(j<0) break;
            ch[j]++;
            for(int k=j+1;k<w;k++)
                ch[k]=ch[k-1]+1;
            for(int j=0;j<=w;j++)
                cout<<ch[j];
            cout<<endl;
        }
        return 0;
    }
    ( ̄3 ̄)a

             //带权中位数,例题:OJ1627

    给出了若干个排列在一条直线上的点,每个点有一个权值,比如说货物量、人数什么的,然后让我们找出使所有点的货物、人集合到一个点的总代价最小的位置//带权中位数就是求这个东西的
    网上看证明一大堆,大概来说,打个比方,现在有一列的东西,每个东西都有一个权值。
    让你在这一列中选一个地方使所有物品到这个位置的距离×权值最小。然后你就可以将这列东西分为两部分,先算出权值和的平均数。
    然后一个从前向后记录前缀和,当这个前缀和大于权值平均数时,这样这列物品就被分为了两部分。
    左半边的所有权值加上中间这个物品的权值大于右边,右边的总权值加上中间的权值大于左边,那么这个点的权值就是带权中位数//大概就是个这个东西

        //oj1627代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    inline int read()
    {
        char ch=getchar();
        int x=0,f=1;
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    struct shadow
    {
        int x,y,v;
    }a[101000];
    bool mycmp(shadow x,shadow y)
    {return x.x<y.x;}
    bool emp(shadow x,shadow y)
    {return x.y<y.y;}
    int main()
    {
        int n=read(),sum=0;
        for(int i=1;i<=n;i++)
        {
            a[i].x=read();a[i].y=read();
            int p=read(),k=read();
            a[i].v=p*k;
            sum+=a[i].v;
        }
        sum=(sum+1)/2;
        sort(a+1,a+1+n,mycmp);
        int ansx=0,ansy=0,tmp=0;
        for(int i=1;i<=n;i++)
        {
            tmp+=a[i].v;
            if(tmp>=sum)
            {
                ansx=a[i].x;
                break;
            }
        }
        tmp=0;
        sort(a+1,a+1+n,emp);
        for(int i=1;i<=n;i++)
        {
            tmp+=a[i].v;
            if(tmp>=sum)
            {
                ansy=a[i].y;
                break;
            }
        }
        cout<<ansx<<' '<<ansy<<endl;
        return 0;
    }
    ٩(๑❛ᴗ❛๑)۶

        (32)dfs序

    void dfs(int p)
    {
        f[p]=true;
        in[p]=++tot;
        for(int i=lin[p];i;i=e[i].next)
        {
            if(!f[e[i].y])
            dfs(e[i].y);
        }
        out[p]=tot;
    }
    (>ω・* )ノ

         (33)2-sat模板//例题:bzoj1823满汉全席

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 3100
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    int get()
    {
        int x;
        char c=getchar();
        while(c!='m'&&c!='h')
            c=getchar();
        if(c=='m') x=read()*2;
        else x=read()*2-1;
        return x;
    }
    struct shadow
    {
        int y,next;
    }a[MAXN*2];
    int lin[MAXN],dfn[MAXN],low[MAXN],q[MAXN],b[MAXN];
    int len=0,ind=0,l=0,sum=0;
    bool vis[MAXN];
    void insert(int x,int y)
    {
        a[++len].y=y;
        a[len].next=lin[x];
        lin[x]=len;
    }
    void trajan(int x)
    {
        low[x]=dfn[x]=++ind;
        vis[x]=1;q[++l]=x;
        for(int i=lin[x];i;i=a[i].next)
            if(!dfn[a[i].y])
            {
                trajan(a[i].y);
                low[x]=min(low[x],low[a[i].y]);
            }
            else if(vis[a[i].y])
                low[x]=min(low[x],dfn[a[i].y]);
        if(low[x]==dfn[x])
        {
            sum++;
            int now=0;
            while(now!=x)
            {
                now=q[l--];
                b[now]=sum;
                vis[now]=0;
            }
        }
    }
    int main()
    {
        int k=read();
        for(int i=1;i<=k;i++)
        {
            ind=l=sum=len=0;
            int n=read(),m=read();
            memset(lin,0,sizeof(lin));
            memset(dfn,0,sizeof(dfn));
            int x,y,X,Y;
            for(int i=1;i<=m;i++)
            {
                x=get();y=get();
                if(x%2==0) X=x--;
                else       X=x++;
                if(y%2==0) Y=y--;
                else       Y=y++;
                insert(X,y);
                insert(Y,x);
            }
            bool f=0;
            for(int i=1;i<=n*2;i++)
                if(!dfn[i])
                    trajan(i);
            for(int i=1;i<=n;i++)
                if(b[i*2]==b[i*2-1])
                {
                    cout<<"BAD"<<endl;
                    f=1;
                    break;
                }
            if(!f)
                cout<<"GOOD"<<endl;
        }
        return 0;
    }
    〒▽〒

       (34)高斯消元

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    double a[1100][1100];
    int n;
    void Gauss()
    {
        int now=1,x,y;
        double t;
        for(int i=1;i<=n;i++)
        {
            for(x=now;x<=n;x++)
                if(a[x][i]!=0)
                    break;
            if(x>n) continue;
            if(x!=now)
                for(int j=1;j<=n+1;j++)
                    swap(a[x][j],a[now][j]);
            t=a[now][i];
            for(int j=1;j<=n+1;j++)
                a[now][j]/=t;
            for(int j=1;j<=n;j++)
                if(j!=now)
                {
                    t=a[j][i];
                    for(int k=1;k<=n+1;k++)
                        a[j][k]-=t*a[now][k];
                }
                now++;
        }
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n+1;j++)
                cin>>a[i][j];
        Gauss();
        for(int i=1;i<=n;i++)
            cout<<(int)round(a[i][n+1])<<endl;
        return 0;
    }
    。◕ᴗ◕。

       (35)矩阵乘法-------斐波那契数列第n项

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<ctime>
    #define K 10000
    #define LL long long
    using namespace std;
    inline int read()
    {
        char ch=getchar();
        int x=0,f=1;
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    struct Matrix
    {
        LL m[2][2];
    };
    Matrix A=
    {
        1,1,
        1,0
    };
    Matrix B=
    {
        1,0,
        0,1
    };
    Matrix multi(Matrix a,Matrix b)
    {
        Matrix c;
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<2;j++)
            {
                c.m[i][j]=0;
                for(int k=0;k<2;k++)
                    c.m[i][j]+=a.m[i][k]*b.m[k][j]%K;
                c.m[i][j]%=K;
            }
        }
        return c;
    }
    Matrix power(Matrix A,int k)
    {
        Matrix ans=B,p=A;
        while(k)
        {
            if(k&1)
            {
                ans=multi(ans,p);
                k--;
            }
            k>>=1;
            p=multi(p,p);
        }
        return ans;
    }
    int main()
    {
        for(;;)
        {
            LL k;
            k=read();
            if(k==-1)
                break;
            if(k==0)
            {
                cout<<0<<endl;
                continue;
            }
            Matrix ans=power(A,k-1);
            cout<<ans.m[0][0]<<endl;
        }
        return 0;
    }
    ❥(ゝω・✿ฺ)

       (36)莫比乌斯函数

    void mobius()
    {
        memset(vis,0,sizeof(vis));
        mu[1]=1;
        for(int i=2;i<=N;i++)
        {
            if(!vis[i])
            {
                mu[i]=-1;
                prime[++l]=i;
            }
            for(int j=1;j<=N;j++)
            {
                if(i*prime[j]>N)
                    break;
                vis[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    mu[i*prime[j]]=0;
                    break;
                }
                mu[i*prime[j]]=-mu[i];
            }
        }
    }
    (*^-^*)

       (37)中国剩余定理//互质版

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    long long n,x,y,M=1;
    void exgcd(long long a,long long b,long long &x,long long &y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return;
        }
        exgcd(b,a%b,x,y);
        int t=x;
        x=y;
        y=t-a/b*y;
    }
    long long a[1100],b[1100];
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i]>>b[i];
            M*=a[i];
        }
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
            long long x,y,Mi=M/a[i];
            exgcd(Mi,a[i],x,y);
            ans=((ans+Mi*x*b[i])%M+M)%M;
        }
        cout<<ans<<endl;
        return 0;
    }
    o( ̄▽ ̄)d

      (38)中国剩余定理//非互质版

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define MAXN 101000
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    ll m[MAXN],q[MAXN];
    void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
    {
        if(b==0)
        {
            d=a;
            x=1;
            y=0;
            return ;
        }
        exgcd(b,a%b,d,x,y);
        int t=x;
        x=y;
        y=t-a/b*y;
    }
    ll M;
    int k;
    ll China()
    {
        ll A=q[1],x,y;
        M=m[1];
        for(int i=2;i<=k;i++)
        {
            ll da=q[i]-A,d;
            exgcd(M,m[i],d,x,y);
            if(da%d) return -1;
            ll t=m[i]/d;
            x*=da/d;
            x=(x%t+t)%t;
            A+=x*M;
            M=M*m[i]/d;
            A=(A+M)%M;
        }
        return A;
    }
    int main()
    {
        while(~scanf("%d",&k))
        {
            for(int i=1;i<=k;i++)
                m[i]=read(),q[i]=read();
            cout<<China()<<endl;
        }
        return 0;
    }
    T^T//poj2891

       (39)求杨辉三角第n行

    1 c[0]=1;
    2 for(int i=1;i<=n;i++)//K为摸数,n为第n行
    3 {    
    4     c[i]=(c[i-1]*(n-i+1)/i)%K;
    5     c[i]%=K;
    6 }

       (40)第二类Stirling数模板//ojp1807例题==模板题

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int a[15][15];//当元素超过20的时候记住用long long
    int main()
    {
        int n,r;
        cin>>n>>r;
        memset(a,0,sizeof(a));
        for(int i=1;i<15;i++)
            a[i][1]=1;
        for(int i=2;i<15;i++)
        {
            for(int j=1;j<=i;j++)
            {
                a[i][j]=a[i-1][j-1]+j*a[i-1][j];
            }
        }
        long long ans=1;
        for(int i=1;i<=r;i++)
            ans*=i;
        cout<<a[n][r]*ans<<endl;
        return 0;
    }
    (ˇˍˇ) 想~

       (41)错位排序

    for(int i=2;i<=n;i++)
    {
        f[i]=f[i-1]+f[i-2];
        f[i]=f[i]*(i-1);
    }    

      

      (42)错位排序-----高精度版//例题HAOI2016 T2放棋子

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 struct shadow
     8 {
     9     int len;
    10     int num[1000];
    11 }a[210],c;
    12 void mul(int x,int y)
    13 {
    14     memset(c.num,0,sizeof(c.num));
    15     c.len=0;
    16     int len=a[y].len;
    17     for(int i=1;i<=len;i++)
    18     {
    19         c.num[i]+=(a[y].num[i]*x);
    20         if(c.num[i]>=10)
    21         {
    22             c.num[i+1]=c.num[i]/10;
    23             c.num[i]%=10;
    24         }
    25     }
    26     len++;
    27     while(c.num[len]>0)
    28     {
    29         c.num[len+1]=c.num[len]/10;
    30         c.num[len++]%=10;
    31     }
    32     c.len=--len;
    33     a[y].len=c.len;
    34     for(int i=1;i<=a[y].len;i++)
    35         a[y].num[i]=c.num[i];
    36 }
    37 void add(int x,int y)
    38 {
    39     memset(c.num,0,sizeof(c));
    40     int len=a[x].len;
    41     if(a[y].len>a[x].len)
    42         len=a[y].len;
    43     for(int i=1;i<=len;i++)
    44     {
    45         c.num[i]+=a[x].num[i]+a[y].num[i];
    46         if(c.num[i]>=10)
    47         {
    48             c.num[i+1]++;
    49             c.num[i]=c.num[i]-10;
    50         }
    51     }
    52     if(c.num[len+1]>0)
    53         len++;
    54     c.len=len;
    55     a[x+1].len=len;
    56     for(int i=1;i<=len;i++)
    57         a[x+1].num[i]=c.num[i];
    58 }
    59 int main()
    60 {
    61     int n;
    62     cin>>n;
    63     a[0].num[1]=1;a[0].len=1;
    64     a[1].num[1]=0;a[1].len=0;
    65     for(int i=2;i<=n;i++)
    66     {
    67         add(i-1,i-2);
    68         mul(i-1,i);
    69     }
    70     for(int i=a[n].len;i>=1;i--)
    71         cout<<a[n].num[i];
    72     cout<<endl;
    73     return 0;
    74 }
    (^o^)/~

      (43)高精度乘以单精度

     1 void mul(int x)
     2 {
     3     memset(c.num,0,sizeof(c.num));
     4     c.len=0;
     5     int len=a.len;
     6     for(int i=1;i<=len;i++)
     7     {
     8         c.num[i]+=(a.num[i]*x);
     9         if(c.num[i]>=10)
    10         {
    11             c.num[i+1]=c.num[i]/10;
    12             c.num[i]%=10;
    13         }
    14     }
    15     len++;
    16     while(c.num[len]>0)
    17     {
    18         c.num[len+1]=c.num[len]/10;
    19         c.num[len++]%=10;
    20     }
    21     c.len=--len;
    22 }

      (44)高精度乘以高精度

     1 #include<iostream> 
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iomanip>
     5 #include<cstring>
     6 #include<cstdio>
     7 using namespace std;
     8 struct bignum
     9 {
    10     int len;
    11     int num[1000];
    12 }a,b,c;
    13 void big(string s,bignum&c)
    14 {
    15     int h;
    16     reverse(s.begin(),s.end());
    17     h=s.size();
    18     for(int i=0;i<h;i++)
    19         c.num[i+1]=int(s[i]-'0');
    20     c.len=s.size();
    21 }
    22 void init()
    23 {
    24     string s1,s2;
    25     cin>>s1>>s2;
    26     big(s1,a);
    27     big(s2,b);
    28 }
    29 
    30 int main()
    31 {
    32     init();
    33     int i,j,len=0;
    34     memset(c.num,0,sizeof(c.num));
    35     for(i=1;i<=a.len;i++)
    36         for(j=1;j<=b.len;j++)
    37         {
    38             int k=i+j-1;
    39             c.num[k]+=a.num[i]*b.num[j];
    40             while(c.num[k]>=10)
    41             {
    42                 c.num[k+1]+=c.num[k]/10;
    43                 c.num[k]%=10;
    44                 k++;
    45             }
    46             if(k>c.len) c.len=k;
    47         }
    48     while(c.num[c.len]==0&&c.len>1)
    49         c.len--;
    50     for(int s=c.len;s>0;s--)
    51         cout<<c.num[s];
    52     return 0;
    53 }

    //折叠有点问题就先不折叠了

       (45)高精度加法

     1 #include<iostream>
     2 #include<string>
     3 #include <stdarg.h> 
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<iomanip>
     7 using namespace std;
     8 struct bignum
     9 {
    10     int len;
    11     int num[1000];
    12 }a,b,c;
    13 void big(string s,bignum&c)
    14 {
    15     int h;
    16     reverse(s.begin(),s.end());
    17     h=s.size();
    18     for(int i=0;i<h;i++)
    19         c.num[i+1]=int(s[i]-'0');
    20     c.len=s.size();
    21 }
    22 void init()
    23 {
    24     string s1,s2;
    25     cin>>s1>>s2;
    26     big(s1,a);
    27     big(s2,b);
    28 }
    29 int main()
    30 {
    31     init();
    32     int len=b.len;
    33     if(a.len>b.len) len=a.len;
    34     for(int i=1;i<=len;i++)
    35     {
    36         c.num[i]+=a.num[i]+b.num[i];
    37         if(c.num[i]>=10)
    38         {
    39             c.num[i+1]++;
    40             c.num[i]=c.num[i]-10;
    41         }
    42     }
    43     if(c.num[len+1]>0)len++;
    44     c.len=len;
    45     for(int i=c.len;i>0;i--)
    46     cout<<c.num[i];
    47     return 0;
    48 }

      

      (46)高精度减法

    //猴式智减法??

     1 #include<iostream> 
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iomanip>
     5 #include<cstring>
     6 #include<cstdio>
     7 using namespace std;
     8 struct bignum
     9 {
    10     int len;
    11     int num[1000];
    12 }a,b,c;
    13 void big(string s,bignum&c)
    14 {
    15     int h;
    16     reverse(s.begin(),s.end());
    17     h=s.size();
    18     for(int i=0;i<h;i++)
    19         c.num[i+1]=int(s[i]-'0');
    20     c.len=s.size();
    21 }
    22 void init()
    23 {
    24     string s1,s2;
    25     cin>>s1>>s2;
    26     big(s1,a);
    27     big(s2,b);
    28 }
    29 
    30 int main()
    31 {
    32     init();
    33     int i,j,len=0;
    34     memset(c.num,0,sizeof(c.num));
    35     for(i=1;i<=a.len;i++)
    36         for(j=1;j<=b.len;j++)
    37         {
    38             int k=i+j-1;
    39             c.num[k]+=a.num[i]*b.num[j];
    40             while(c.num[k]>=10)
    41             {
    42                 c.num[k+1]+=c.num[k]/10;
    43                 c.num[k]%=10;
    44                 k++;
    45             }
    46             if(k>c.len) c.len=k;
    47         }
    48     while(c.num[c.len]==0&&c.len>1)
    49         c.len--;
    50     for(int s=c.len;s>0;s--)
    51         cout<<c.num[s];
    52     return 0;
    53 }

      

      (47)高精度除法.....留个坑QAQ

      (48)线段树----区间查询最大值,区间修改

     1 struct shadow
     2 {
     3     int delta;
     4     int maxx;    
     5 }tree[MAXN*4];
     6 int search(int l,int r,int root)
     7 {
     8     int mid,templ,tempr;
     9     if(y<l||x>r)
    10         return -9999999999;
    11     if(x<=l&&y>=r)
    12         return tree[root].maxx;
    13     mid=(l+r)/2;
    14     int D=tree[root].delta;
    15     tree[root*2].delta+=D; tree[root*2+1].maxx+=D;
    16     tree[root*2+1].delta+=D; tree[root*2+1].maxx+=D;
    17     tree[root].delta=0;
    18     templ=search(l,mid,root*2);
    19     tempr=search(mid+1,r,root*2+1);
    20     return max(templ,tempr);
    21 }
    22 void updata(int l,int r,int root)
    23 {
    24     int mid;
    25     if(x>r||y<l)
    26         return;
    27     if(x<=l&&y>=r)
    28     {
    29         tree[root].maxx++;
    30         tree[root].delta++;
    31         return;
    32     }
    33     mid=(l+r)/2;
    34     int D=tree[root].delta;tree[root].delta=0;
    35     tree[root*2].delta+=D;tree[root*2].maxx+=D;
    36     tree[root*2+1].delta+=D;tree[root*2+1].maxx+=D;
    37     updata(l,mid,root*2);
    38     updata(mid+1,r,root*2+1);
    39     tree[root].maxx=max(tree[root*2].maxx,tree[root*2+1].maxx);
    40 }
    ╰( ̄▽ ̄)╭

       (49)树状数组求逆序对

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define MAXN 101000
     7 using namespace std;
     8 int n;
     9 int c[MAXN],a[MAXN];
    10 int lowbit(int x)
    11 {return x&-x;}
    12 void add(int i,int x)
    13 {
    14     while(i<=MAXN)
    15     {
    16         c[i]+=x;
    17         i+=lowbit(i);
    18     }
    19 }
    20 int sum(int i)
    21 {
    22     int ans=0;
    23     while(i>0)
    24     {
    25         ans+=c[i];
    26         i-=lowbit(i);
    27     }
    28     return ans;
    29 }
    30 int main()
    31 {
    32     //freopen("shadow.in","r",stdin);
    33     //freopen("shadow.out","w",stdout);
    34     int n;
    35     cin>>n;
    36     int ans=0;
    37     for(int i=1;i<=n;i++)
    38     {
    39         int x;
    40         cin>>x;
    41         ans+=i-sum(x+1)-1;
    42         //cout<<i<<"-----"<<sum(x-1)<<endl;
    43         add(x+1,1);
    44     }
    45     cout<<ans<<endl;
    46     return 0;
    47 }
    $_$

       (50)欧拉函数(O(n))

     1 void Euler(int x)
     2 {
     3     memset(check,0,sizeof(check));
     4     int l=0;
     5     for(int i=2;i<=x;i++)
     6     {
     7         if(!check[i])
     8         {
     9             prime[++l]=i;
    10             phi[i]=i-1;
    11         }
    12         for(int j=1;j<=l&&prime[j]*i<=x;j++)
    13         {
    14             check[i*prime[j]]=1;
    15             if(i%prime[j])
    16                 phi[i*prime[j]]=phi[i]*(prime[j]-1);
    17             else
    18             {
    19                 phi[i*prime[j]]=phi[i]*prime[j];
    20                 break;
    21             }
    22         }
    23     }
    24 }
    (⊙o⊙)

         (51)多重背包//有n个物品和一个容量为C的背包,第i种物品的重量是w[i],价值是v[i],数量为a[i]。求把那些物品放入背包中价值总和最大

     1 void bag()
     2 {
     3     for(int i=1;i<=n;i++)
     4     {
     5         if(w[i]*a[i]>C)
     6         {
     7             for(int c=0;c<=C;c++)
     8                 if(c>=w[i])
     9                     f[c]=max(f[c],f[c-w[i]]+v[i]);
    10         }
    11         else
    12         {
    13             int sum=a[i],k=1;
    14             while(k<sum)
    15             {
    16                 for(int c=C;c>=k*w[i];c--)
    17                     f[c]=max(f[c],f[c-k*w[i]]+k*v[i]);
    18                 sum-=k;
    19                 k+=k;
    20             }
    21             for(int c=C;c>=sum*w[i];c--)
    22                 f[c]=max(f[c],f[c-sum*w[i]]+sum*v[i]);
    23         }
    24     }
    25 }
    (*@ο@*)

        (52)割点---trajan

     1 void trajan(int x)//----割点-----//
     2 {
     3     low[x]=dfn[x]=++ind;
     4     for(int i=lin[x];i;i=a[i].next)
     5     {
     6         int tmp=a[i].y;
     7         if(!dfn[tmp])
     8         {
     9             trajan(tmp);
    10             if(x==h)
    11                 son++;
    12             else
    13             {
    14                 low[x]=min(low[x],low[tmp]);
    15                 if(low[tmp]>=dfn[x]&&!c[x])
    16                 {
    17                     ans++;
    18                     c[x]=1;
    19                 }
    20             }
    21         }
    22         else
    23             low[x]=min(low[x],dfn[tmp]);
    24     }
    25     return ;
    26 }
    27 void work()
    28 {
    29     for(int i=1;i<=n;i++)
    30         if(!dfn[i])
    31         {
    32             son=0;
    33             h=i;
    34             trajan(i);
    35             if(son>1&&c[i]==false)
    36             {
    37                 c[i]=1;
    38                 ans++;
    39             }
    40         }
    41     //ans为图中的割点数目,if(c[i])那么i就为一个割点
    42 }
    (~ ̄▽ ̄)~

      (53)割边---trajan

     1 void trajan(int x,int p=0)//----割边----//
     2 {
     3     dfn[x]=low[x]=++ind;
     4     for(int i=lin[x];i;i=a[i].next)
     5     {
     6         int tmp=a[i].y;
     7         if(!dfn[tmp])
     8         {
     9             trajan(tmp,x);
    10             low[x]=min(low[x],dfn[tmp]);
    11             if(dfn[x]<low[tmp])
    12             {
    13                 ans[++l].y=x;
    14                 ans[l].next=tmp;
    15             }
    16         }
    17         else if(dfn[tmp]<low[x]&&tmp!=p)
    18             low[x]=dfn[tmp];
    19     }//ans[]数组中保存的即为割边
    20 }
    ⁽⁽ଘ( ˊᵕˋ )ଓ⁾⁾*

        第十一回更

       作为退役选手的我又回来更新了....//弱弱的补个坑

        (54)线段树----单点修改和区间求值

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define MAXN 110000
     7 using namespace std;
     8 inline int read()
     9 {
    10     int x=0,f=1;
    11     char ch=getchar();
    12     while(ch>'9'||ch<'0')
    13     {
    14         if(ch=='-')
    15             f=-1;
    16         ch=getchar();
    17     }
    18     while(ch>='0'&&ch<='9')
    19     {
    20         x=x*10+ch-'0';
    21         ch=getchar();
    22     }
    23     return x*f;
    24 }
    25 struct drt
    26 {
    27     int v,delta;
    28 }tree[MAXN*4];
    29 int x,y;
    30 void updata(int l,int r,int root)//单点修改
    31 {
    32     int mid;
    33     if(x<l||x>r)
    34         return ;
    35     if(l==r)
    36     {
    37         tree[root].v=y;
    38         tree[root].delta=y;
    39         return ;
    40     }
    41     mid=(l+r)>>1;
    42     int d=tree[root].delta;
    43     tree[root<<1].delta+=d;tree[root<<1].v+=d;
    44     tree[root<<1|1].delta+=d;tree[root<<1|1].v+=d;
    45     tree[root].delta=0;
    46     updata(l,mid,root<<1);
    47     updata(mid+1,r,root<<1|1);
    48     tree[root].v=tree[root<<1].v+tree[root<<1|1].v;
    49 }
    50 int search(int l,int r,int root)//区间[x,y]求值
    51 {
    52     int mid,tmpl,tmpr;
    53     if(x>r||y<l)
    54         return 0;
    55     if(x<=l&&y>=r)
    56         return tree[root].v;
    57     mid=(l+r)>>1;
    58     int d=tree[root].delta;
    59     tree[root<<1].v+=d;tree[root<<1].delta+=d;
    60     tree[root<<1|1].v+=d;tree[root<<1|1].delta+=d;
    61     tree[root].delta=0;
    62     tmpl=search(l,mid,root<<1);
    63     tmpr=search(mid+1,r,root<<1|1);
    64     return (tmpl+tmpr);
    65 }
    66 int main()
    67 {
    68     memset(tree,0,sizeof(0));
    69     int n=read(),w=read();
    70     for(int i=1;i<=w;i++)
    71     {
    72         char ch;
    73         cin>>ch;
    74         int xx=read(),yy=read();
    75         if(ch=='x')//单点修改
    76         {
    77             x=xx;y=yy;
    78             updata(1,n,1);
    79         }
    80         else
    81         {
    82             x=xx;y=yy;
    83             int ans=search(1,n,1);//求值
    84             cout<<ans<<endl;
    85         }
    86     }
    87     return 0;
    88 }
    o( ̄ヘ ̄o#)

        (55)线段树----区间修改和区间求值

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define MAXN 101000
      7 #define ll long long
      8 using namespace std;
      9 inline ll read()
     10 {
     11     ll x=0,f=1;
     12     char ch=getchar();
     13     while(ch>'9'||ch<'0')
     14     {
     15         if(ch=='-')
     16             f=-1;
     17         ch=getchar();
     18     }
     19     while(ch>='0'&&ch<='9')
     20     {
     21         x=x*10+ch-'0';
     22         ch=getchar();
     23     }
     24     return x*f;
     25 }
     26 struct drt
     27 {
     28     ll v,d;
     29 }a[MAXN*4];
     30 ll x,y,k;
     31 ll s[MAXN];
     32 void build(ll l,ll r,ll root)
     33 {
     34     ll mid;
     35     if(l==r)
     36     {
     37         a[root].v=s[l];
     38         return ;
     39     }
     40     mid=(l+r)>>1;
     41     a[root].d=0;
     42     build(l,mid,root<<1);
     43     build(mid+1,r,root<<1|1);
     44     a[root].v=a[root<<1].v+a[root<<1|1].v;
     45 }
     46 void f(ll root,ll l,ll r,ll k)
     47 {
     48     a[root].d+=k;
     49     a[root].v+=k*(r-l+1);
     50 }
     51 void updata(ll l,ll r,ll root)
     52 {
     53     ll mid;
     54     if(x>r||y<l)
     55         return ;
     56     if(x<=l&&y>=r)
     57     {
     58         a[root].v+=k*(r-l+1);
     59         a[root].d+=k;
     60         return ;
     61     }
     62     mid=(l+r)>>1;
     63     f(root<<1,l,mid,a[root].d);
     64     f(root<<1|1,mid+1,r,a[root].d);
     65     a[root].d=0;
     66     if(x<=mid) updata(l,mid,root<<1);
     67     if(y>mid) updata(mid+1,r,root<<1|1);
     68     a[root].v=a[root<<1].v+a[root<<1|1].v;
     69 }
     70 ll search(ll l,ll r,ll root)
     71 {
     72     ll mid,sum=0;
     73     if(x>r||y<l)
     74         return 0;
     75     if(x<=l&&y>=r)
     76         return a[root].v;
     77     mid=(l+r)>>1;
     78     int D=a[root].d;
     79     f(root<<1,l,mid,D);
     80     f(root<<1|1,mid+1,r,D);
     81     a[root].d=0;
     82     if(x<=mid) sum+=search(l,mid,root<<1);
     83     if(y>mid) sum+=search(mid+1,r,root<<1|1);
     84      return sum;
     85 }
     86 int main()
     87 {
     88     ll n=read(),m=read();
     89     for(int i=1;i<=n;i++)
     90         s[i]=read();
     91     build(1,n,1);
     92     for(int i=1;i<=m;i++)
     93     {
     94         ll c=read();
     95         if(c==1)
     96         {
     97             x=read();y=read();
     98             k=read();
     99             updata(1,n,1);
    100         }
    101         else
    102         {
    103             x=read(),y=read();
    104             ll ans=search(1,n,1);
    105             cout<<ans<<endl;
    106         }
    107     }
    108     return 0;
    109 }
    i╮(╯﹏╰)╭

  • 相关阅读:
    jquery点击展开-收起
    jquery-选择器
    导航-三级联动
    Apriori算法
    K近邻算法
    宝贵数据集——用于数据挖掘、机器学习、文本挖掘
    Microsoft 神经网络分析算法
    Java网络爬虫
    写Java须知CPU缓存
    MapReduce实现计数
  • 原文地址:https://www.cnblogs.com/lcyhaha/p/7413455.html
Copyright © 2011-2022 走看看