• Code Library 打印面


    ---

    /*==============================================*
     | Code Library
    *==============================================*/
    /** head-file **/
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    /** define-for **/
    #define REP(i, n) for (int i=0;i<int(n);++i)
    #define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
    #define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
    #define REP_1(i, n) for (int i=1;i<=int(n);++i)
    #define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
    #define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
    #define REP_N(i, n) for (i=0;i<int(n);++i)
    #define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)
    #define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)
    #define REP_1_N(i, n) for (i=1;i<=int(n);++i)
    #define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)
    #define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)
    /** define-useful **/
    #define clr(x,a) memset(x,a,sizeof(x))
    #define sz(x) int(x.size())
    #define see(x) cerr<<#x<<" "<<x<<endl
    #define se(x) cerr<<" "<<x
    #define pb push_back
    #define mp make_pair
    /** test **/
    #define Display(A, n, m) {                      
        REP(i, n){                                  
            REP(j, m) cout << A[i][j] << " ";       
            cout << endl;                           
        }                                           
    }
    #define Display_1(A, n, m) {                    
        REP_1(i, n){                                
            REP_1(j, m) cout << A[i][j] << " ";     
            cout << endl;                           
        }                                           
    }
    using namespace std;
    /** typedef **/
    typedef long long LL;
    /** Add - On **/
    const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };
    const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };
    const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };
    const int MOD = 1000000007;
    const int INF = 0x3f3f3f3f;
    const long long INFF = 1LL << 60;
    const double EPS = 1e-9;
    const double OO = 1e15;
    const double PI = acos(-1.0); //M_PI;
    const int maxn=11111;
    const int maxm=1111111;
    int n,m;
    /*==============================================*
     | 建图
     | INIT: init(int n):void
     | CALL: addedge(int u,int v,int c):void
    *==============================================*/
    struct EdgeNode{
        int to;
        int w;
        int next;
    };
    struct Graph{
        int head[maxn];
        EdgeNode edges[maxm];
        int edge,n;
        void init(int n){
            memset(head,-1,sizeof(head));
            this->n=n;
            edge=0;
        }
        void addedge(int u,int v,int c){
            edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
    };
    /*==============================================*
     | Dijkstra+堆优化
     | INIT: init(n);addedge(u,v,c);节点编号0~n
     | CALL: dijkstra(int s);dis[]:最短路;pre[]:前驱
    *==============================================*/
    struct HeapNode{
        int d,u;
        HeapNode(){}
        HeapNode(int a,int b):d(a),u(b){}
        bool operator<(const HeapNode& rhs) const{
            return d>rhs.d;
        }
    };
    struct Dijkstra{
        EdgeNode edges[maxm];
        int head[maxn];
        int edge,n;
        void init(int n){
            this->n=n;
            memset(head,-1,sizeof(head));
            edge=0;
        }
        void addedge(int u,int v,int c){
            edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        bool done[maxn];
        int dis[maxn];
        int pre[maxn];
        void dijkstra(int s){
            priority_queue<HeapNode>que;
            for (int i=0;i<=n;i++) dis[i]=INF;
            dis[s]=0;
            memset(done,0,sizeof(done));
            que.push(HeapNode(0,s));
            while (!que.empty()){
                HeapNode x=que.top();
                que.pop();
                int u=x.u;
                if (done[u]) continue;
                done[u]=true;
                for (int i=head[u];i!=-1;i=edges[i].next){
                    int v=edges[i].to;
                    int w=edges[i].w;
                    if (dis[v]>dis[u]+w){
                        dis[v]=dis[u]+w;
                        pre[v]=u;
                        que.push(HeapNode(dis[v],v));
                    }
                }
            }
        }
    };
    /*==============================================*
     | BellmanFord+队列优化
     | INIT: init(n);addedge(u,v,c);节点编号0~n
     | CALL: spfa(int s):bool;dist[]:最短路
    *==============================================*/
    struct BellmanFord{
        EdgeNode edges[maxm];
        int head[maxn],edge,n;
        bool vis[maxn];
        int outque[maxn];
        queue<int>que;
        int dis[maxn];
        void addedge(int u,int v,int c){
            edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        void init(int n){
            memset(head,-1,sizeof(head));
            edge=0;
            this->n=n;
        }
        bool spfa(int s){
            int u;
            for (int i=0;i<=n;i++) dis[i]=INF;
            memset(vis,0,sizeof(vis));
            memset(outque,0,sizeof(outque));
            while (!que.empty()) que.pop();
            que.push(s);
            vis[s]=true;
            dis[s]=0;
            while (!que.empty()){
                u=que.front();
                que.pop();
                vis[u]=false;
                outque[u]++;
                if (outque[u]>n) return false;
                for (int i=head[u];i!=-1;i=edges[i].next){
                    int v=edges[i].to;
                    int w=edges[i].w;
                    if (dis[v]==INF||dis[v]>dis[u]+w){
                        dis[v]=dis[u]+w;
                        if (!vis[v]){
                            vis[v]=true;
                            que.push(v);
                        }
                    }
                }
            }
            return true;
        }
    };
    /*==============================================*
     | 强连通分量-Tarjan
     | INIT: init(n);addedge(u,v);节点编号0~n-1
     | CALL: find_scc();sccno[x]:节点x所属强连通分量
    *==============================================*/
    struct Tarjan{
        int head[maxn];
        EdgeNode edges[maxm];
        int edge,n;
        void init(int n){
            memset(head,-1,sizeof(head));
            this->n=n;
            edge=0;
        }
        void addedge(int u,int v,int c=0){
            edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        int pre[maxn],lowlink[maxn],sccno[maxn],scc_cnt,dfs_clock;
        stack<int>stk;
        void dfs(int u){
            pre[u]=lowlink[u]=++dfs_clock;
            stk.push(u);
            for (int i=head[u];i!=-1;i=edges[i].next){
                int v=edges[i].to;
                if (!pre[v]){
                    dfs(v);
                    lowlink[u]=min(lowlink[u],lowlink[v]);
                }
                else if (!sccno[v]){
                    lowlink[u]=min(lowlink[u],pre[v]);
                }
            }
            if (lowlink[u]==pre[u]){
                scc_cnt++;
                int x;
                do{
                    x=stk.top();
                    stk.pop();
                    sccno[x]=scc_cnt;
                }while (x!=u);
            }
        }
        void find_scc(){
            dfs_clock=scc_cnt=0;
            memset(sccno,0,sizeof(sccno));
            memset(pre,0,sizeof(pre));
            while (!stk.empty()) stk.pop();
            for (int i=0;i<n;i++) if (!pre[i]) dfs(i);
        }
    };
    /*==============================================*
     | 点双连通/割点/桥/边双连通
     | INIT: init(n);addedge(u,v);无向图;节点编号1~n
     | CALL: find_bcc():点双连通/割点/桥
     |       find_block():边双连通,先要求出桥
     |       iscut[]:割点;EdgeNode_1.cut:桥
     |       vector<int>bcc[x]:双连通分量x所包含的节点
     |       bccno[x]:节点x所属的点双连通分量,割点的值无意义
     |       block[x]:节点x所属的边双连通分量
    *==============================================*/
    struct EdgeNode_1{
        int to;
        int w;
        int next;
        bool cut;
    };
    struct Edge{
        int u;
        int v;
        Edge(){}
        Edge(int a,int b):u(a),v(b){}
    };
    struct Bcc_Graph{
        int head[maxn];
        EdgeNode_1 edges[maxm];
        int edge,n;
        void init(int n){
            memset(head,-1,sizeof(head));
            this->n=n;
            edge=0;
        }
        void addedge(int u,int v,int c=0){
            edges[edge].cut=0,edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        //点双连通/割点/桥
        int dfn[maxn],low[maxn],bccno[maxn],dfs_clock,bcc_cnt;
        bool iscut[maxn];
        vector<int>bcc[maxn];
        stack<Edge>stk;
        int dfs(int u,int fa){
            int lowu=dfn[u]=++dfs_clock;
            int child=0;
            for (int i=head[u];i!=-1;i=edges[i].next){
                int v=edges[i].to;
                if (v==fa) continue;
                Edge e=Edge(u,v);
                if (!dfn[v]){
                    stk.push(e);
                    child++;
                    int lowv=dfs(v,u);
                    lowu=min(lowu,lowv);
                    if (dfn[u]<=lowv){
                        iscut[u]=true;//割点
                        //BEGIN 求点双连通分量
                        bcc_cnt++;
                        bcc[bcc_cnt].clear();
                        Edge x;
                        do{
                            x=stk.top();
                            stk.pop();
                            if (bccno[x.u]!=bcc_cnt){
                                bcc[bcc_cnt].push_back(x.u);
                                bccno[x.u]=bcc_cnt;
                            }
                            if (bccno[x.v]!=bcc_cnt){
                                bcc[bcc_cnt].push_back(x.v);
                                bccno[x.v]=bcc_cnt;
                            }
                        }while (x.u!=u||x.v!=v);
                        //END
                    }
                    if (dfn[u]<lowv){//cut 桥
                        edges[i].cut=true;
                        edges[i^1].cut=true;
                    }
                }
                else if (dfn[v]<dfn[u]){
                    stk.push(e);//BEGIN-END 点双连通
                    lowu=min(lowu,dfn[v]);
                }
            }
            if (fa<0&&child==1) iscut[u]=0;//割点
            low[u]=lowu;
            return lowu;
        }
        void find_bcc(){
            while (!stk.empty()) stk.pop();
            memset(dfn,0,sizeof(dfn));
            memset(iscut,0,sizeof(iscut));
            memset(bccno,0,sizeof(bccno));
            dfs_clock=bcc_cnt=0;
            for (int i=1;i<=n;i++){
                if (!dfn[i]) dfs(i,-1);
            }
        }
        //边双连通分量
        int block[maxn];
        int vis[maxn];
        int b_num;
        void b_dfs(int u){
            vis[u]=true;
            block[u]=b_num;
            for (int i=head[u];i!=-1;i=edges[i].next)
            {
                if (edges[i].cut) continue;
                int v=edges[i].to;
                if (!vis[v]) b_dfs(v);
            }
        }
        void find_block(){
            memset(block,0,sizeof(block));
            memset(vis,0,sizeof(vis));
            b_num=0;
            for (int i=1;i<=n;i++){
                if (!vis[i]){
                    b_num++;
                    b_dfs(i);
                }
            }
        }
    };
    /*==============================================*
     | TwoSAT
     | INIT: init(n);addedge(u,v);节点编号0~n-1
     | CALL: add_clause(x,xval,y,yval) x=xval or y=yval
     |       add_con(x,xval) x=xval
     |       solve():bool;mark[i]:选取i
    *==============================================*/
    struct TwoSAT{
        int head[maxn*2];
        EdgeNode edges[maxm*2];
        int edge,n;
        bool mark[maxn*2];
        int S[maxn*2],c;
        void init(int n){
            this->n=n;
            memset(mark,0,sizeof(mark));
            memset(head,-1,sizeof(head));
            edge=0;
        }
        void addedge(int u,int v){
            edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        // x = xval or y = yval
        void add_clause(int x,int xval,int y,int yval){
            x=x*2+xval;
            y=y*2+yval;
            addedge(x^1,y);
            addedge(y^1,x);
        }
        // x = xval
        void add_con(int x,int xval){
            x=x*2+xval;
            addedge(x^1,x);
        }
        bool dfs(int x){
            if (mark[x^1]) return false;
            if (mark[x]) return true;
            mark[x]=true;
            S[c++]=x;
            for (int i=head[x];i!=-1;i=edges[i].next)
                if (!dfs(edges[i].to)) return false;
            return true;
        }
        bool solve(){
            for (int i=0;i<n*2;i+=2)
                if (!mark[i]&&!mark[i+1]){
                    c=0;
                    if (!dfs(i)){
                        while (c>0) mark[S[--c]]=false;
                        if (!dfs(i+1)) return false;
                    }
                }
            return true;
        }
    };
    /*==============================================*
     | TwoSAT-Tarjan强连通
     | INIT: init(n),addedge(u,v),节点0~n-1
     | CALL: add_self(x,xval,y,yval) x!=xval->y=yval
     |       solve():bool
    *==============================================*/
    struct TWOSAT{
        int head[maxn*2];
        EdgeNode edges[maxm*2];
        int edge,n;
        void init(int n){
            this->n=2*n;
            memset(head,-1,sizeof(head));
            edge=0;
        }
        void addedge(int u,int v){
            edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        // x = xval or y = yval
        void add_clause(int x,int xval,int y,int yval){
            x=x*2+xval;
            y=y*2+yval;
            addedge(x^1,y);
            addedge(y^1,x);
        }
        //x=xval
        void add_con(int x,int xval){
            x=x*2+xval;
            addedge(x^1,x);
        }
        //x!=xval->y=yval
        void add_self(int x,int xval,int y,int yval){
            x=x*2+xval;
            y=y*2+yval;
            addedge(x,y);
        }
        int pre[maxn],lowlink[maxn],sccno[maxn],scc_cnt,dfs_clock;
        stack<int>stk;
        void dfs(int u){
            pre[u]=lowlink[u]=++dfs_clock;
            stk.push(u);
            for (int i=head[u];i!=-1;i=edges[i].next){
                int v=edges[i].to;
                if (!pre[v]){
                    dfs(v);
                    lowlink[u]=min(lowlink[u],lowlink[v]);
                }
                else if (!sccno[v]){
                    lowlink[u]=min(lowlink[u],pre[v]);
                }
            }
            if (lowlink[u]==pre[u]){
                scc_cnt++;
                int x;
                do{
                    x=stk.top();
                    stk.pop();
                    sccno[x]=scc_cnt;
                }while (x!=u);
            }
        }
        void find_scc(int n){
            dfs_clock=scc_cnt=0;
            memset(sccno,0,sizeof(sccno));
            memset(pre,0,sizeof(pre));
            while (!stk.empty()) stk.pop();
            for (int i=0;i<n;i++) if (!pre[i]) dfs(i);
        }
        bool solve(){
            find_scc(n);
            for (int i=0;i<n;i+=2){
                if (sccno[i]==sccno[i^1]) return false;
            }
            return true;
        }
    };
    /*==============================================*
     | Dinic最大流
     | INIT: prepare(n,S,T);addedge(u,v,c);节点0~n
     | CALL: Dinic_flow():int
    *==============================================*/
    struct edgenode{
        int to,flow,next;
    };
    struct Dinic{
        int node,src,dest,edge;
        int head[maxn],work[maxn],dis[maxn],q[maxn];
        edgenode edges[maxm];
        void prepare(int _node,int _src,int _dest){
            node=_node,src=_src,dest=_dest;
            memset(head,-1,sizeof(head));
            edge=0;
        }
        void addedge(int u,int v,int c){
            edges[edge].flow=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
            edges[edge].flow=0,edges[edge].to=u,edges[edge].next=head[v],head[v]=edge++;
        }
        bool Dinic_bfs(){
            int i,u,v,l,r=0;
            for (i=0; i<node; i++) dis[i]=-1;
            dis[q[r++]=src]=0;
            for (l=0; l<r; l++){
                for (i=head[u=q[l]]; i!=-1; i=edges[i].next){
                    if (edges[i].flow&&dis[v=edges[i].to]<0){
                        dis[q[r++]=v]=dis[u]+1;
                        if (v==dest) return true;
                    }
                }
            }
            return false;
        }
        int Dinic_dfs(int u,int exp){
            if (u==dest) return exp;
            for (int &i=work[u],v,tmp; i!=-1; i=edges[i].next){
                if (edges[i].flow&&dis[v=edges[i].to]==dis[u]+1&&
                    (tmp=Dinic_dfs(v,min(exp,edges[i].flow)))>0){
                    edges[i].flow-=tmp;
                    edges[i^1].flow+=tmp;
                    return tmp;
                }
            }
            return 0;
        }
        int Dinic_flow(){
            int i,ret=0,delta;
            while (Dinic_bfs()){
                for (i=0;i<node;i++) work[i]=head[i];
                while (delta=Dinic_dfs(src,INF)) ret+=delta;
            }
            return ret;
        }
    };
    /*==============================================*
     | 最小费用最大流
     | INIT: prepare(n,S,T);addedge(u,v,f,c);编号0~n-1
     | CALL: spfaflow():int
    *==============================================*/
    struct edgenode_1{
        int to;//边的指向
        int flow;//边的容量
        int cost;//边的费用
        int next;//链表的下一条边
    };
    struct MinCost{
        edgenode_1 edges[maxm];
        int node,src,dest,edge;//node节点数,src源点,dest汇点,edge边数
        int head[maxn],p[maxn],dis[maxn],q[maxn],vis[maxn];
        //head链表头,p记录可行流上节点对应的反向边,dis计算距离
        void prepare(int _node=0,int _src=0,int _dest=0){
            node=_node,src=_src,dest=_dest;
            memset(head,-1,sizeof(head));
            memset(vis,0,sizeof(vis));
            edge=0;
        }
        void addedge(int u,int v,int f,int c){
            edges[edge].flow=f;edges[edge].cost=c;edges[edge].to=v;
            edges[edge].next=head[u];head[u]=edge++;
            edges[edge].flow=0;edges[edge].cost=-c;edges[edge].to=u;
            edges[edge].next=head[v];head[v]=edge++;
        }
        bool spfa(){
            int i,u,v,l,r=0,tmp;
            for (i=0;i<node;i++) dis[i]=INF;
            dis[q[r++]=src]=0;
            p[src]=p[dest]=-1;
            for (l=0;l!=r;((++l>=maxn)?l=0:l)){
                for (i=head[u=q[l]],vis[u]=false;i!=-1;i=edges[i].next){
                    if (edges[i].flow&&dis[v=edges[i].to]>(tmp=dis[u]+edges[i].cost)){
                        dis[v]=tmp;
                        p[v]=i^1;
                        if (vis[v]) continue;
                        vis[q[r++]=v]=true;
                        if (r>=maxn) r=0;
                    }
                }
            }
            return p[dest]>=0;
        }
        int spfaflow(){
            int i,ret=0,delta;
            while (spfa()){//按记录原路返回求流量
                for (i=p[dest],delta=INF;i>=0;i=p[edges[i].to]){
                    delta=min(delta,edges[i^1].flow);
                }
                for (int i=p[dest];i>=0;i=p[edges[i].to]){
                    edges[i].flow+=delta;
                    edges[i^1].flow-=delta;
                }
                ret+=delta*dis[dest];
            }
            return ret;
        }
    };


    ---

    ---

    /*==============================================*
     | 最大公约数-辗转相除
    *==============================================*/
    int gcd(int a,int b){
        if (b==0) return a;
        return gcd(b,a%b);
    }
    /*==============================================*
     | 扩展欧几里得
     | ax+by=gcd(a,b)
    *==============================================*/
    int extgcd(int a,int b,int& x,int& y){
        int d=a;
        if (b!=0){
            d=extgcd(b,a%b,y,x);
            y-=(a/b)*x;
        }else{
            x=1;y=0;
        }
        return d;
    }
    /*==============================================*
     | 素数-埃氏筛法
    *==============================================*/
    int prime[maxn];
    bool is_prime[maxn+1];
    int sieve(int n){
        int p=0;
        for (int i=0;i<=n;i++) is_prime[i]=true;
        is_prime[0]=is_prime[1]=false;
        for (int i=2;i<=n;i++){
            if (is_prime[i]){
                prime[p++]=i;
                for (int j=2*i;j<=n;j+=i) is_prime[j]=false;
            }
        }
        return p;
    }
    /*==============================================*
     | 快速幂
    *==============================================*/
    LL modPow(LL x,LL n,LL mod){
        if (n==0) return 1;
        LL res=modPow(x*x%mod,n/2,mod);
        if (n&1) res=res*x%mod;
        return res;
    }
    /*==============================================*
     | 高斯消元-列主元
     | 求解Ax=b,A为矩阵 无解/多解时返回空数组
    *==============================================*/
    const double eps=1e-8;
    typedef vector<double>vec;
    typedef vector<vec>mat;
    vec gaussJordan(const mat& A,const vec& b){
        int n=A.size();
        mat B(n,vec(n+1));
        for (int i=0;i<n;i++)
            for (int j=0;j<n;j++) B[i][j]=A[i][j];
        for (int i=0;i<n;i++) B[i][n]=b[i];
        for (int i=0;i<n;i++){
            int pivot=i;
            for (int j=i;j<n;j++){
                if (abs(B[j][i])>abs(B[pivot][i])) pivot=j;
            }
            swap(B[i],B[pivot]);
            if (abs(B[i][i]<eps)) return vec();//无解或多解
            for (int j=i+1;j<=n;j++) B[i][j]/=B[i][i];
            for (int j=0;j<n;j++){
                if (i!=j){
                    for (int k=i+1;k<=n;k++) B[j][k]-=B[j][i]*B[i][k];
                }
            }
        }
        vec x(n);
        for (int i=0;i<n;i++) x[i]=B[i][n];
        return x;
    }
    /*==============================================*
     | 逆元
     | ax≡b(mod m) x=a逆×b
     | gcd(a,m)!=1逆元不存在
    *==============================================*/
    int modInverse(int a,int m){
        int x,y;
        extgcd(a,m,x,y);
        return (m+x%m)%m;
    }
    

    ---

    /*==============================================*
     | 矩阵快速幂
    *==============================================*/
    const int M=10000;
    typedef vector<int>vec;
    typedef vector<vec>mat;
    mat mul(mat &A,mat &B){
        mat C(A.size(),vec(B[0].size()));
        for (int i=0;i<(int)A.size();i++){
            for (int k=0;k<(int)B.size();k++){
                for (int j=0;j<(int)B[0].size();j++){
                    C[i][j]=(C[i][j]+A[i][k]*B[k][j])%M;
                }
            }
        }
        return C;
    }
    mat pow(mat A,LL n){
        mat B(A.size(),vec(A.size()));
        for (int i=0;i<(int)A.size();i++){
            B[i][i]=1;
        }
        while (n>0){
            if (n&1) B=mul(B,A);
            A=mul(A,A);
            n>>=1;
        }
        return B;
    }
    


    ---



  • 相关阅读:
    loj6145. 「2017 山东三轮集训 Day7」Easy
    CF1019E Raining season
    CF1261F Xor-Set
    Python笔试——递归算法学习
    Python笔试——贪心算法
    Python笔试——万万没想到抓捕孔连顺
    Python笔试——雀魂启动
    Python学习——正则表达式
    Python笔试——毕业旅行问题
    Python笔试——Stern-Brocot tree
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681643.html
Copyright © 2020-2023  润新知