Code Library 打印面

来源:互联网 发布:批量下载歌词软件 编辑:程序博客网 时间:2024/04/28 18:09

---

/*==============================================*\ | 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;}


---



原创粉丝点击