• 省选模板大杂烩


    Code:

    #include <cstdio>
    #include <cstdlib>
    #include <queue> 
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>    
    #define maxn 1000000
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;    
    //动态树
    namespace LCT{
        int ch[maxn][2];
        int tag[maxn],lazy[maxn]; 
        int sta[maxn]; 
        int sumv[maxn]; 
        int siz[maxn];   
        int maxv[maxn],minv[maxn]; 
        int lson(int x){ return ch[x][0]; }
        int rson(int x){ return ch[x][1]; }    
        int get(int x) { return ch[f[x]][1] == x; }
        int isRoot(int x){ return !(ch[f[x]][1]==x||ch[f[x]][0]==x); }
        void addv(int x,int delta){
            sumv[x] += siz[x] * delta; 
            lazy[x] += delta;  
        }
        void rev(int x){
            tag[x] ^= 1; 
            if(tag[x])
                swap(ch[x][0],ch[x][1]),tag[x] = 0; 
        }
        void pushdown(int x){
            if(lazy[x]) {
                addv(lson(x),lazy[x]); 
                addv(rson(x),lazy[x]); 
                lazy[x] = 0; 
            }
            if(tag[x])rev(lson(x)),rev(rson(x)),tag[x] = 0; 
        }
        void pushup(int x){
            sumv[x] = sumv[lson(x)] + sumv[rson(x)] + val[x]; 
            siz[x] = siz[lson(x)] + siz[rson(x)] + 1;         
            maxv[x] = max(maxv[lson(x)],maxv[rson(x)]); 
            minv[x] = min(minv[son(x)],minv[rson(x)]); 
        }
        void rotate(int x){
            int old=f[x],oldf=f[old],which=get(x); 
            if(!isRoot(old)) ch[oldf][ch[oldf][1]==old] = x; 
            ch[old][which]=ch[x][which^1],f[ch[old][which]]=old; 
            ch[x][which^1] = old,f[old] = x,f[x] = oldf; 
            pushup(old),pushup(x); 
        }
        void splay(int x){
            int v=0,u=x; 
            sta[++v] = x; 
            while(!isRoot(u)) sta[++v] = f[u],u=f[u]; 
            while(v) pushdown(sta[v--]); 
            u=f[u]; 
            for(int fa;(fa=f[x])!=u;rotate(x)) 
                if(f[fa]!=u) rotate(get(fa)==get(x) ? fa: x); 
        }
        void Access(int x){
            for(int y=0;x;y=x,x=f[x]) 
                splay(x),ch[x][1]=y; 
        }
        void makeRoot(int x){
            Access(x),splay(x),rev(x);    
        }
        void link(int x,int y){
            makeRoot(x),f[x]=y;
        }
        //x为y的父亲
        void cut(int x,int y){
            makeRoot(x),Access(y),splay(y); 
            ch[y][0]=f[ch[y][0]]=0; 
            pushup(y); 
        }
    }; 
    //树状数组 
    namespace BIT{
        int n;
        int C[maxn]; 
        int lowbit(int t) { return t & (-t); }
        void update(int x,int delta){
            while(x <= n) {
                C[x] += delta; 
                x += lowbit(x); 
            } 
        }
        int query(int x){
            int sum=0; 
            while(x >= 0)  sum += C[x],x -= lowbit(x); 
            return sum; 
        }
    }; 
    //主席树(不修改)
    namespace Chair_Tree1{
        int node_cnt; 
        int ls[maxn],rs[maxn]; 
        int sumv[maxn]; 
        void build(int l,int r,int &o){
            if(l>r) return; 
            o=++node_cnt; 
            if(l==r) return ; 
            int mid=(l+r)>>1;
            build(l,mid,ls[o]); 
            build(mid+1,r,rs[o]);  
        }
        int update(int l,int r,int k,int o){
            int oo=++node_cnt; 
            sumv[oo] = sumv[o] + 1; 
            ls[oo] = ls[o];
            rs[oo] = rs[o]; 
            if(l==r) return oo; 
            int mid=(l+r)>>1;
            if(k<=mid) ls[oo] = update(l,mid,k,ls[o]); 
            else rs[oo] = update(mid+1,r,k,rs[o]); 
            return oo; 
        }
        int query(int u,int v,int l,int r,int k){
            if(l==r) return l; 
            int mid=(l+r)>>1;
            int delta = sumv[ls[v]] - sumv[ls[u]]; 
            if(delta >= k) return query(ls[u],ls[v],l,mid,k); 
            else return query(rs[u],rs[v],mid+1,r,k-delta); 
        }
    };  
    //主席树2(修改)        
    namespace Chair_Tree2{
        struct Queries{
            int c,l,r,k; 
            Queries(int c=0,int l=0,int r=0,)
        }asks[maxn]; 
        int lson[maxn*10],rson[maxn*10],root[maxn];
        int temp[2][200],count[2],sumv[maxn*10]; 
        int cnt_Tree; 
        int lowbit(int t){ return t & (-t); }       
        void insert(int l,int r,int pos,int delta,int &o){
            if(!o) o=++cnt_Tree; 
            sumv[o] += delta; 
            if(l==r) return ; 
            int mid=(l+r)>>1;
            if(pos<=mid)
                insert(l,mid,pos,delta,lson[o]); 
            else 
                insert(mid+1,r,pos,delta,rson[o]);
        }
        void update(int pos,int val,int delta){
            for(int i=pos;i<=n;i+=lowbit(i)) 
                insert(1,n,val,delta,root[i]); 
        }
        int query(int l,int r,int k){
            if(l==r) return l; 
            int sum=0; 
            for(int i=1;i<=count[0];++i) sum+=sumv[lson[temp[0][i]]];
            for(int i=1;i<=count[1];++i) sum-=sumv[lson[temp[1][i]]]; 
            int mid=(l+r)>>1;
            if(k<=sum){
                for(int i=1;i<=count[0];++i) temp[0][i]=lson[temp[0][i]]; 
                for(int i=1;i<=count[1];++i) temp[1][i]=lson[temp[1][i]]; 
                return query(l,mid,k); 
            }
            else {
                for(int i=1;i<=count[0];++i) temp[0][i]=rson[temp[0][i]];
                for(int i=1;i<=count[1];++i) temp[1][i]=rson[temp[1][i]]; 
                return query(mid+1,r,k-sum); 
            }
        }
        int Query(int l,int r,int k){
            memset(temp,0,sizeof(temp)); 
            count[0]=count[1]=0; 
            for(int i=r;i>=1;i-=lowbit(i)) 
                temp[0][++count[0]] = root[i]; 
            for(int i=l-1;i>=1;i-=lowbit(i)) 
                temp[1][++count[0]] = root[i]; 
            return query(1,n,k); 
        }
    }; 
    //并查集
    namespace Union_Find{
        int n; 
        int p[maxn]; 
        void init(){
            for(int i=1;i<=n;++i) p[i]=i;  
        }
        int find(int x){
            return p[x]==x?x:p[x] = find(p[x]); 
        }
        void merge(int a,int b){
            int x=find(a),y=find(b); 
            if(x==y) return; 
            p[x] = y; 
        }
    };      
    //可并堆
    namespace M_heap{
        int val[maxn]; 
        int ch[maxn][2]; 
        int dis[maxn]; 
        int siz[maxn]; 
        int merge(int a,int b){
            if(!a||!b) return a + b; 
            if(val[a] < val[b]) swap(a,b); 
            ch[a][1] = merge(ch[a][1],b); 
            if(dis[ch[a][1]]>dis[ch[a][0]])  swap(ch[a][0],ch[a][1]); 
            dis[a] = dis[ch[a][0]] + 1; 
            sumv[a] = sumv[ch[a][0]] + sumv[ch[a][1]] + val[a]; 
            siz[a] = siz[ch[a][0]] + siz[ch[a][1]] + 1;
            return a;  
        }
        void pop(int &a){
            int t=merge(ch[a][0],ch[a][1]); 
            siz[a] = sumv[a] = val[a] = ch[a][0] = ch[a][1] = 0; 
            a=t; 
        }
    };      
    //线段树 
    namespace Segment_Tree{ 
        #define ll long long  
        long long mod; 
        int val[maxn]; 
        ll sumv[maxn<<2],mult[maxn<<2],addv[maxn<<2]; 
        void pushdown(int o,int l,int r){
            int mid=(l+r)>>1,ls=(o<<1),rs=(o<<1)|1; 
            if(mult[o]!=1) {
                sumv[ls] = (sumv[ls] * mult[o])%mod;
                sumv[rs] = (sumv[rs] * mult[o])%mod; 
                mult[ls] = (mult[ls] * mult[o])%mod; 
                mult[rs] = (mult[rs] * mult[o])%mod; 
                addv[ls] = (addv[ls] * mult[o])%mod; 
                addv[rs] = (addv[rs] * mult[o])%mod; 
                mult[o] = 1; 
            }
            if(addv[o] != 0) {
                if(mid>=l) sumv[ls] += (mid-l+1) *addv[o]; 
                if(mid+1<=r) sumv[rs] += (r-mid) * addv[o]; 
                addv[ls] += addv[o],addv[rs] += addv[o]; 
                addv[o]=0; 
            }
        }
        void build_Tree(int l,int r,int o){
            if(l>r) return; 
            mult[o]=1;
            if(l==r) {
                sumv[o] = val[l]%mod; 
                return; 
            }
            int mid=(l+r)>>1,ls=(o<<1),rs=(o<<1)|1; 
            build_Tree(l,mid,ls); 
            build_Tree(mid+1,r,rs); 
            sumv[o] = (sumv[ls] + sumv[rs])%mod; 
        }
        void update_mult(int l,int r,int o,int L,int R,int delta){
            if(l > r || r < L || l > R) return; 
            if(l>=L&&r<=R) {
                sumv[o]*=delta; 
                mult[o]*=delta;
                addv[o]*=delta; 
                return; 
            }
            int mid=(l+r)>>1;
            pushdown(o,l,r); 
            update_mult(l,mid,(o<<1),L,R,delta); 
            update_mult(mid+1,r,(o<<1)|1,L,R,delta); 
            sumv[o] = sumv[(o<<1)] + sumv[(o<<1)|1]; 
        }
        void update_add(int l,int r,int o,int L,int R,int delta) {
            if(l > r || r < L || l > R) return; 
            if(l>=L&&r<=R){
                sumv[o]+=delta*(r-l+1);   
                addv[o]+=delta; 
                return; 
            }
            int mid=(l+r)>>1;
            pushdown(o,l,r); 
            update_add(l,mid,(o<<1),L,R,delta); 
            update_add(mid+1,r,(o<<1)|1,L,R,delta);
            sumv[o] = sumv[(o<<1)] + sumv[(o<<1)|1]; 
        }
        int query(int l,int r,int o,int L,int R){
            if(l > r || r < L || l > R) return 0;      
            if(l >= L && r <= R) return sumv[o]; 
            int mid=(l+r)>>1; 
            pushdown(o,l,r); 
            return query(l,mid,(o<<1),L,R)+query(mid+1,r,(o<<1)|1,L,R); 
        }
    }; 
    //树链剖分
    namespace Heavy_Edge{
        #define ll long long 
        #define lson (o<<1)
        #define rson (o<<1)|1
        ll mod;
        int n; 
        int head[maxn],nex[maxn<<1],to[maxn<<1]; 
        int p[maxn],son[maxn],dep[maxn],top[maxn]; 
        int cnt,cnt2; 
        ll sumv[maxn<<2]; 
        int lazy[maxn];
        int A[maxn],st[maxn],ed[maxn],val[maxn]; 
        void addedge(int u,int v){
            nex[++cnt]=head[u],head[u]=cnt,to[cnt]= v;
        }
        void dfs1(int u,int fa,int cur){
            p[u]=fa,dep[u]=cur,siz[u]=1; 
            for(int i=head[u];i;i=nex[i])
                if(to[i]!=fa) {
                    dfs1(to[i],u,cur+1); 
                    siz[u]+=siz[to[i]]; 
                    if(son[u]==-1||siz[to[i]]>siz[son[u]]) 
                        son[u] = to[i]; 
                }
            
        }
        void dfs2(int u,int tp){
            top[u]=tp,A[u]=++cnt2,st[u]=cnt2; 
            if(son[u]!=-1) dfs2(son[u],tp); 
            for(int i=head[u];i;i=nex[i])
                if(to[i]!=p[u]&&to[i]!=son[u]) 
                    dfs2(to[i],to[i]); 
            ed[u]=cnt2; 
        }
        void pushdown(int l,int r,int o){
            if(lazy[o]){
                int mid=(l+r)>>1;
                lazy[lson]+=lazy[o],lazy[rson]+=lazy[o]; 
                sumv[lson]+=(mid-l+1)*lazy[o]; 
                sumv[rson]+=(r-mid)*lazy[o]; 
                lazy[o]=0; 
            }
        }
        void build(int l,int r,int o,int arr[]){
            if(l>r) return; 
            if(l==r) {
                sumv[o]=arr[l];
                return; 
            }
            int mid=(l+r)>>1;
            build(l,mid,lson,arr); 
            build(mid+1,r,rson,arr); 
            sumv[o] = sumv[lson] + sumv[rson]; 
        }
        void update(int l,int r,int k,int L,int R,int o){
            if(l>r||r<L||l>R) return;
            if(l>=L&&r<=R){
                lazy[o]+=k;
                sumv[o]+=(r-l+1)*k;
                return; 
            }
            int mid=(l+r)>>1;
            pushdown(l,r,o); 
            update(l,mid,k,L,R,lson);
            update(mid+1,r,k,L,R,rson); 
            sumv[o] = sumv[lson] + sumv[rson]; 
        }
        long long query(int l,int r,int o,int L,int R){
            if(l>r||r<L||l>R) return 0; 
            if(l>=L&&r<=R) return sumv[o]; 
            int mid=(l+r)>>1;
            pushdown(l,r,o); 
            return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R); 
        }
        void up(int x,int y,int del){
            while(top[x]!=top[y]){
                if(dep[top[x]>dep[top[y]]) swap(x,y); 
                update(1,n,del,A[top[y]],A[y],1); 
            }
            if(dep[x]<dep[y]) swap(x,y); 
            update(1,n,del,A[y],A[x],1); 
        }
        long long look_up(int x,int y){
            long long sum=0;
            while(top[x]!=top[y]) {
                if(dep[top[x]]>dep[top[y]]) swap(x,y); 
                sum+=query(1,n,1,A[top[y]],A[y]); 
                y=p[top[y]]; 
            }
            if(dep[y]>dep[x]) swap(x,y); 
            sum+=query(1,n,1,A[y],A[x]);     
            return sum; 
        }
    };  
    //最近公共祖先 
    namespace LCA{
        #define LOG 21 
        int cnt; 
        int f[22][maxn],dep[maxn];
        int head[maxn],to[maxn],nex[maxn]; 
        void addedge(int u,int v){
            nex[++cnt] = head[u],head[u]=cnt,to[cnt] = v; 
        }
        void dfs(int u,int fa){
            dep[u] = dep[fa] + 1; 
            f[0][u]=fa; 
            for(int i=1;i<LOG;++i) f[i][u]=f[i-1][f[i-1][u]]; 
            for(int i=head[u];i;i=nex[i])
                if(to[i]!=fa)dfs(to[i],u); 
        }
        int query(int x,int y){
            if(dep[x]<dep[y]) swap(x,y); 
            if(dep[x]!=dep[y]){
                for(int i=LOG-1;i>=0;--i) 
                    if(dep[f[i][y]]<=dep[x]) y=f[i][y]; 
            }
            if(x==y) return x; 
            for(int i=LOG-1;i>=0;--i)
                if(f[i][x]!=f[i][y])
                    x=f[i][x],y=f[i][y]; 
            return f[0][x]; 
        }
    }; 
    //线性筛(欧拉函数,莫比乌斯函数)
    namespace get_prime{
        int tot; 
        int prime[maxn],is[maxn];
        int mu[maxn],phi[maxn]; 
        void get_prime(){
            mu[1]=1; 
            phi[1]=1; 
            for(int i=2;i<maxn;++i){
                if(!is[i]) {
                    prime[++tot]=i;
                    phi[i]=i-1;
                    mu[i]=-1; 
                }
                for(int j=1;j<=cnt&&prime[j]*i<maxn;++j){
                    is[prime[j]*i]=1; 
                    if(i%prime[j]!=0) {
                        phi[i*prime[j]]=phi[i]*(prime[j]-1); 
                        mu[i*prime[j]]=-mu[i]; 
                    }
                    else {
                        phi[i*prime[j]]=prime[j]*phi[i]; 
                        mu[i*prime[j]]=0; 
                        break; 
                    }
                }
            }
        }
    }; 
    //权值线段树可持久化合并                 
    namespace Seg{
        struct Segment_Tree{
            int l,r,maxv; 
        }node[maxn<<2];
        int root[maxn],nodes; 
        int newnode(){ return ++nodes; }
        void update(int p,int l,int r int &o){
            if(!o) o=newnode(); 
            if(l==r){
                node[o].maxv+=1; 
                return ; 
            }
            int mid=(l+r)>>1;          
            if(p<=mid) 
                update(p,l,mid,node[o].l); 
            else 
                update(p,mid+1,r,node[o].r);
            node[o].maxv=max(node[node[o].l].maxv,node[node[o].r].maxv); 
            return o; 
        }      
        int merge(int x,int y,int l,int r){
            if(!x||!y) return x+y; 
            int o=newnode(),mid=(l+r)>>1;
            if(l==r){
                node[o].maxv=node[x].maxv+node[y].maxv; 
                return o; 
            }
            node[o].l=merge(node[x].l,node[y].l,l,mid); 
            node[o].r=merge(node[x].r,node[y].r,mid+1,r); 
            node[o].maxv=max(node[node[o].l].maxv,node[node[o].r].maxv); 
            return o; 
        }
        int query_max(int l,int r,int L,int R,int o){
            if(!o||l>r||r<L||l>R) return 0; 
            if(l>=L&&r<=R) return node[o].maxv; 
            int mid=(l+r)>>1; 
            return max(query_max(l,mid,L,R,node[o].l),query_max(mid+1,r,L,R,node[o].r)); 
        }
    }; 
    //权值线段树合并(永无乡)
    namespace Seg2{
        int cnt=0;
        int p[maxn],ls[maxn],rs[maxn],sumv[maxn],exe[maxn],map[maxn]; 
        int find(int x){
            return p[x] == x ? x : p[x] = find(p[x]); 
        }
        //初始化(只插入一个点QAQ) 
        void update(int l,int r,int k,int &o,int fa){
            if(!o) o=++cnt; 
            p[o]=fa;
            ++sumv[o]; 
            if(l==r) {
                exe[map[k]]=0;
                return;        
            }
            int mid=(l+r)>>1;
            if(k<=mid) 
                update(l,mid,k,ls[o],fa); 
            else 
                update(mid+1,r,k,rs[o],fa); 
        }
        int merge_tree(int x,int y){
            if(!x||!y) return x+y; 
            sumv[x] += sumv[y]; 
            ls[x] = merge(ls[x],ls[y]); 
            rs[x] = merge(rs[x],rs[y]); 
            return x; 
        }
        int query(int l,int r,int k,int o){
            if(l==r) return l;
            int mid=(l+r)>>1;
            if(k<=sumv[ls[o]]) 
                return query(l,mid,k,ls[o]); 
            else 
                return query(mid+1,r,k-sumv[rs[o]],rs[o]); 
        }
    }; 
    //dijkstra
    namespace Dijkstra{
        #define maxn 1000000 
        #define inf 2000000000
        int n,m,s; 
        int cnt; 
        int head[maxn],nex[maxn<<1],to[maxn<<1],val[maxn<<1]; 
        void addedge(int u,int v,int c){
            nex[++cnt] = head[u];
            head[u]=cnt;
            to[cnt] = v; 
            val[cnt] = c; 
        }
        struct Node{
            int dist,u;
            Node(int dist,int u):dist(dist),u(u){}
            bool operator < (Node v)const{
                return v.dist < dist; 
            }
        }; 
        priority_queue<Node>Q; 
        int done[maxn],d[maxn]; 
        void dijkstra(){
            memset(done,0,sizeof(done)); 
            memset(d,0,sizeof(d)); 
            for(int i=0;i<maxn;++i) d[i]=inf; 
            d[0]=d[s]=0;  
            Q.push(Node(d[0],s)); 
            while(!Q.empty()){
                int u=Q.top().u; Q.pop(); 
                if(done[u]) continue; 
                done[u]=1; 
                for(int v=head[u];v;v=nex[v]){
                    if(d[u]+val[v]<d[to[v]]){
                        d[to[v]] = d[u]+val[v];
                        Q.push(Node(d[to[v]],to[v])); 
                    }
                }
            }
        }
        int main(){
            scanf("%d%d%d",&n,&m,&s);
            for(int i=1;i<=m;++i) {
                int a,b,c; 
                scanf("%d%d%d",&a,&b,&c);
                addedge(a,b,c); 
            }
            dijkstra(); 
            for(int i=1;i<=n;++i) printf("%d ",d[i]); 
            return 0; 
        }
    }; 
    //SPFA
    namespace SPFA{
        #define maxn 1000000 
        #define inf 2147483647
        int head[maxn],to[maxn<<1],nex[maxn<<1],val[maxn<<1];
        int cnt; 
        int n,m,s; 
        int inq[maxn],d[maxn]; 
        deque<int>Q; 
        void addedge(int u,int v,int c){
            nex[++cnt] = head[u], head[u] = cnt,to[cnt] = v,val[cnt] = c; 
        }
        void spfa(){
            for(int i=0;i<maxn;++i) d[i] = inf; 
            memset(inq,0,sizeof(inq)); 
            Q.push_back(s); 
            inq[s] = 1; 
            d[s] = 0; 
            while(!Q.empty()){
                int u=Q.front(); Q.pop_front(); 
                inq[u] = 0; 
                for(int v=head[u];v;v=nex[v])
                    if(d[to[v]] > d[u] + val[v]) {
                        d[to[v]] = d[u] + val[v]; 
                        if(!inq[to[v]]) {
                            inq[to[v]] = 1; 
                            if(Q.empty() || d[Q.front()] >= d[to[v]] - 2000)  
                                Q.push_front(to[v]); 
                            else 
                                Q.push_back(to[v]); 
                        }
                    }
            }
        }
        int main(){
            scanf("%d%d%d",&n,&m,&s);
            for(int i=1;i<=m;++i) {
                int a,b,c; 
                scanf("%d%d%d",&a,&b,&c);
                addedge(a,b,c);
            }
            spfa();
            for(int i=1;i<=n;++i) printf("%d ",d[i]); 
            return 0; 
        }
    }; 
    //真 - 广义后缀自动机
    namespace EX_SAM{
        #define maxn 1000000 
        #define digma 30 
        int ch[maxn][31],f[maxn],dis[maxn];
        int last,tot; 
        int ans; 
        void init(){ last=tot=1; }
        void ins(int c){
            if(ch[p][c]) {     
                int q=ch[p][c]; 
                if(dis[q] == dis[p] + 1) last=q; 
                else {
                    int nq=++tot; last=nq; 
                    dis[nq] = dis[p] + 1; 
                    memcpy(ch[nq],ch[q],sizeof(ch[q])); 
                    f[nq] = f[q],f[q]=nq; 
                    while(p && ch[p][c] == q) ch[p][c] = nq; 
                }             
            }
            else {
                int np=++tot; p=last,last=np; dis[np] = dis[p] + 1; 
                while(p && !ch[p][c]) ch[p][c] = np,p=f[p]; 
                if(!p) 
                    f[np] = 1; 
                else {
                    int q=ch[p][c] 
                    if(dis[q] == dis[p] + 1)    f[np] = q; 
                    else {
                        int nq=++tot; 
                        dis[nq] = dis[p] + 1;
                        memcpy(ch[nq],ch[q],sizeof(ch[q])); 
                        f[nq] = f[q],f[q] = f[np] = nq;                    
                        while(p && ch[p][c] == q) ch[p][c] = nq,p=f[p]; 
                    }
                }
                ans+=dis[np] - dis[f[np]]; 
            }
        }
    };   
    //伪(广义后缀自动机)
    namespace SAM2{
        int ch[maxn][31],f[maxn],dis[maxn];
        int last,tot; 
        int ans; 
        void init(){ last=tot=1; }
        void ins(int c){
            int p=last,np=++tot; last=np; dis[np] = dis[p] + 1; 
            while(p && !ch[p][c]) ch[p][c] = np,p=f[p]; 
            if(!p) f[np] = 1;
            else {
                int q=ch[p][c]; 
                if(dis[q] == dis[p] + 1) f[np] = q; 
                else {
                    int nq=++tot; 
                    dis[nq] = dis[p] + 1;     
                    memcpy(ch[nq],ch[q],sizeof(ch[q]));  
                    f[nq] = f[q],f[q] = f[np] = nq; 
                    while(p && ch[p][c] == q) ch[p][c] = nq, p=f[p]; 
                }
            }
            ans += dis[np] - dis[f[np]]; 
        }
    };      
    //缩点 + 拓扑排序   
    namespace Tarjan{
        #define maxn 1000000 
        #define ll long long 
        map<int,int>ed[maxn]; 
        int scc,sig; 
        int vis[maxn]; 
        int du[maxn]; 
        int idx[maxn];   
        int pre[maxn],low[maxn]; 
        int val[maxn];       
        long long value[maxn];  
        long long ans[maxn]; 
        stack<int>S; 
        queue<int>Q; 
        struct graph{
            int cnt; 
            int head[maxn],to[maxn<<1],nex[maxn<<1];  
            void addedge(int u,int v){
                nex[++cnt] = head[u],head[u]=cnt,to[cnt] = v; 
            }
        }G1,G2; 
        void tarjan(int u){
            S.push(u); 
            vis[u] = 1;         
            pre[u] = low[u] = ++scc; 
            for(int v=G1.head[u];v;v=G1.nex[v]){
                if(!vis[G1.to[v]]) {
                    tarjan(G1.to[v]); 
                    low[u] = min(low[u],low[G1.to[v]]); 
                }
                else if(vis[G1.to[v]] == 1) low[u] = min(low[u],pre[G1.to[v]]); 
            }
            if(pre[u] == low[u]) {
                ++sig; 
                for(;;){
                    int a=S.top(); S.pop(); 
                    vis[a] = -1,idx[a] = sig; 
                    value[sig] += (ll)val[a]; 
                    if(a==u) break;     
                }
            }     
        }   
        void toposort(){
            for(int i=1;i<=sig;++i) 
                for(int j=G2.head[i];j;j=G2.nex[j])   ++du[G2.to[j]]; 
            for(int i=1;i<=sig;++i) if(du[i]==0) Q.push(i),ans[i] = value[i]; 
            while(!Q.empty()){
                int u=Q.front(); Q.pop(); 
                for(int v=G2.head[u];v;v=G2.nex[v]){ 
                    ans[G2.to[v]] = max(ans[G2.to[v]],ans[u] + value[G2.to[v]]); 
                    --du[G2.to[v]]; 
                    if(du[G2.to[v]]==0) Q.push(G2.to[v]); 
                }
            }
            long long fin=0; 
            for(int i=1;i<=sig;++i) 
                fin=max(fin,ans[i]); 
            printf("%lld",fin); 
        }
        int main(){
            int n,m,a,b; 
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;++i) scanf("%d",&val[i]);     
            for(int i=1;i<=m;++i) {   
                scanf("%d%d",&a,&b);      
                G1.addedge(a,b); 
            }
            for(int i=1;i<=n;++i) if(!vis[i]) tarjan(i);                       
            for(int i=1;i<=n;++i) 
                for(int v=G1.head[i];v;v=G1.nex[v])
                    if(idx[i]!=idx[G1.to[v]] && !ed[idx[i]][idx[G1.to[v]]])  
                        G2.addedge(idx[i],idx[G1.to[v]]),ed[idx[i]][idx[G1.to[v]]]=1;    
            toposort(); 
            return 0; 
        }
    }; 
    //网络流 - 最大流(vector 存边)
    namespace Dinic{
        #define maxn 200000 
        #define inf 10000000 
        int N,M,S,T; 
        struct Edge{
            int from,to,cap;
            Edge(int u,int v,int c):from(u),to(v),cap(c){} 
        }; 
        vector<int>G[maxn]; 
        vector<Edge>edges; 
        queue<int>Q; 
        void addedge(int u,int v,int c){
            edges.push_back(Edge(u,v,c)); 
            edges.push_back(Edge(v,u,0)); 
            int m=edges.size(); 
            G[u].push_back(m-2);
            G[v].push_back(m-1); 
        }
        int d[maxn],vis[maxn]; 
        int current[maxn]; 
        int BFS(){
            memset(d,0,sizeof(d)); 
            memset(vis,0,sizeof(vis)); 
            d[S] = 0,vis[S] = 1; Q.push(S); 
            while(!Q.empty()){
                int u=Q.front(); Q.pop();         
                int m=G[u].size(); 
                for(int i=0;i<m;++i) {
                    Edge r = edges[G[u][i]]; 
                    if(!vis[r.to] && r.cap > 0) {
                        d[r.to] = d[u] + 1; 
                        vis[r.to] = 1; 
                        Q.push(r.to); 
                    }
                }
            }
            return vis[T]; 
        }
        int dfs(int x,int cur){
            if(x == T) return cur; 
            int flow=0,f; 
            int m=G[x].size(); 
            for(int i=current[x];i<m;++i) {        
                current[x] = i; 
                int u=G[x][i];        
                Edge r = edges[u]; 
                if(d[r.to] == d[x] + 1 && r.cap >0) {
                    f = dfs(r.to,min(cur,r.cap)); 
                    if(f > 0) {
                        flow += f,cur -= f;           
                        edges[u].cap -= f,edges[u ^ 1].cap += f; 
                    }       
                }      
                if(cur == 0) break; 
            }
            return flow; 
        }
        int maxflow(){
            int flow = 0; 
            while(BFS()){
                memset(current,0,sizeof(current)); 
                flow += dfs(S,inf); 
            }
            return flow; 
        }
    };
    //最小费用流
    namespace MCMF{ 
        #define inf 2000000 
        #define maxn 50004    
        #define ll long long 
        struct Edge{
            int from,to,cap,cost; 
            Edge(int u,int v,int c,int f):from(u),to(v),cap(c),cost(f){} 
        }; 
        long long ans; 
        int flow; 
        int n,m,s,t; 
        queue<int>Q; 
        vector<int>G[maxn]; 
        vector<Edge>edges;         
        void addedge(int u,int v,int c,int f){
            edges.push_back(Edge(u,v,c,f)); 
            edges.push_back(Edge(v,u,0,-f)); 
            int m = edges.size(); 
            G[u].push_back(m-2);
            G[v].push_back(m-1); 
        }   
        int d[maxn],inq[maxn],a[maxn],flow2[maxn];  
        int SPFA(){
            for(int i=1;i<maxn;++i) d[i] = flow2[i] = inf; 
            memset(inq,0,sizeof(inq)); 
            inq[s] = 1,d[s] = 0; Q.push(s); 
            int f; 
            while(!Q.empty()){
                int u = Q.front(); Q.pop(); inq[u] = 0; 
                int sz = G[u].size(); 
                for(int i=0;i<sz;++i) {
                    Edge r = edges[G[u][i]]; 
                    if(r.cap > 0 && d[r.to] > d[u] + r.cost) {
                        d[r.to] = d[u] + r.cost; 
                        a[r.to] = G[u][i]; 
                        flow2[r.to] = min(r.cap,flow2[u]); 
                        if(!inq[r.to]) {      
                            inq[r.to] = 1;
                            Q.push(r.to); 
                        }
                    } 
                }
            }
            if(d[t] == inf) return 0;       
            f = flow2[t];  
            flow += f;                  
            int u = edges[a[t]].from; 
            edges[a[t]].cap -= f; 
            edges[a[t] ^ 1].cap += f; 
            while(u != s){
                edges[a[u]].cap -= f; 
                edges[a[u] ^ 1].cap += f; 
                u = edges[a[u]].from; 
            }
            ans += (ll) (d[t] * f);      
            return 1; 
        }     
        int maxflow(){
            while(SPFA()); 
            return flow; 
        }
        long long getcost()   { return ans;  }
        int main(){
            scanf("%d%d%d%d",&n,&m,&s,&t); 
            for(int i=1;i<=m;++i) {
                int a,b,c,d;
                scanf("%d%d%d%d",&a,&b,&c,&d); 
                addedge(a,b,c,d); 
            }      
            printf("%d ",maxflow()); 
            printf("%lld",getcost()); 
            return 0; 
        }
    }; 
    //AC 自动机
    namespace AC_Automaton{
        #define idx str[i]-'a'
        #define root 0 
        #define sigma 27 
        int ch[maxn][sigma],last[maxn],fail[maxn],end[maxn]; 
        int nodes; 
        int newnode(){ return ++nodes; }
        void ins(char str[],int id){
            int n=strlen(str); 
            int pos = root; 
            for(int i=0;i<n;++i) {
                if(!ch[pos][idx]) 
                    ch[pos][idx] = newnode(); 
                pos = ch[pos][idx]; 
            }
            G[pos].push_back(id); 
            end[pos] = 1; 
            map[id] = pos; 
        }
        queue<int>Q; 
        void build(){
            for(int i=0;i<sigma;++i) 
                if(ch[root][i]) {
                    Q.push(ch[root][i]),fail[ch[root][i]]=root; 
                }
            while(!Q.empty()){
                int u = Q.front();Q.pop(); 
                for(int i=0;i<sigma;++i) {
                    int r=ch[u][i]; 
                    if(!r) {
                        ch[u][i]=ch[fail[u]][i]; 
                        continue; 
                    }
                    Q.push(r); 
                    fail[r] = ch[fail[u]][i]; 
                    last[t] = end[fail[r]] ? fail[r]: last[fail[r]]; 
                }    
            }
        }
        void print(int j){
            while(j) {
                if(end[j]) tag[j] += 1; 
                j = last[j]; 
            }
        }
        void query(char str[]){
            int j = root; 
            for(int i = 0;i < cnt; ++i) {
                if(str[i]=='#') j = root; 
                else {
                    j = ch[j][idx]; 
                    print(j); 
                }
            }
        }
    };    
    //KD-TREE
    namespace KDtree{     
        int tot;
        int d; 
        int ans; 
        int n;
        int m;                             
        void init(){ tot = n, ans = inf;  }
        int newnode(){ return ++tot; }
        struct Data{
            int ch[2],minv[2],maxv[2],w,sum,p[2];      
        }node[maxn];
        bool cmp(Data i,Data j){
            return i.p[d] == j.p[d] ? i.p[d^1] < j.p[d^1]: i.p[d] < j.p[d]; 
        }
        int isin(int o,int x1,int y1,int x2,int y2){
            if(node[o].minv[0]>=x1&&node[o].maxv[0]<=x2&&node[o].minv[1]>=y1&&node[o].maxv[1]<=y2) return 1;
            return 0;  
        }
        int isout(int o,int x1,int y1,int x2,int y2){
            if(node[o].minv[0] > x2 || node[o].maxv[0] < x1) return 1; 
            if(node[o].minv[1] > y2 || node[o].maxv[1] < y1) return 1;
            return 0; 
        }
        void getmax(int &a,int b){ if( b > a ) a = b; }
        void getmin(int &a,int b){ if( b < a ) a = b; }
        void pushup(int o,int x){
            getmin(node[o].minv[0],node[x].minv[0]); 
            getmin(node[o].minv[1],node[x].minv[1]); 
            getmax(node[o].maxv[1],node[x].maxv[1]); 
            getmax(node[o].maxv[0],node[x].maxv[0]); 
            node[o].sum += node[x].sum; 
        }
        int build(int l,int r,int o){
            int mid = (l + r) >> 1;              
            d = o ; nth_element(node+l,node+mid,node+r+1,cmp); 
            node[mid].minv[0] = node[mid].maxv[0] = node[mid].p[0]; 
            node[mid].minv[1] = node[mid].maxv[1] = node[mid].p[1]; 
            node[mid].sum = node[mid].w; 
            node[mid].ch[0] = node[mid].ch[1] = 0; 
            if(l < mid) node[mid].ch[0] = build(l,mid - 1,o ^ 1), pushup(mid,node[mid].ch[0]); 
            if(r > mid) node[mid].ch[1] = build(mid + 1, r, o ^ 1), pushup(mid,node[mid].ch[1]); 
            return mid; 
        }
        void update(int &o,Data x,int de){
            if(!o) {
                o = newnode();  
                node[o].p[0] = node[o].maxv[0] = node[o].minv[0] = x.p[0]; 
                node[o].p[1] = node[o].minv[1] = node[o].maxv[1] = x.p[1]; 
                return; 
            }
            if(x.p[de] < node[o].p[de]) update(node[o].ch[0],x,de^1),pushup(o,node[o].ch[0]); 
            else update(node[o].ch[1],x,de^1),pushup(o,node[o].ch[1]); 
        }
        int getdis(int o,int x1,int y1){
            int dis = 0;
            if(x1 < node[o].minv[0]) dis += node[o].minv[0] - x1;
            if(x1 > node[o].maxv[0]) dis += x1 - node[o].maxv[0]; 
            if(y1 < node[o].minv[1]) dis += node[o].minv[1] - y1; 
            if(y1 > node[o].maxv[1]) dis += y1 - node[o].maxv[1]; 
            return dis; 
        }
        void query(int o,int x1,int y1){
            int dn = abs(node[o].p[0] - x1) + abs(node[o].p[1] - y1),dl,dr; 
            ans = min(ans,dn); 
            dl = node[o].ch[0] ? getdis(node[o].ch[0],x1,y1) : inf; 
            dr = node[o].ch[1] ? getdis(node[o].ch[1],x1,y1) : inf; 
            if(dl < dr) {
                if(dl < ans) query(node[o].ch[0],x1,y1); 
                if(dr < ans) query(node[o].ch[1],x1,y1);             
            }
            else {
                if(dr < ans) query(node[o].ch[1],x1,y1); 
                if(dl < ans) query(node[o].ch[0],x1,y1); 
            }
        }
        int main(){       
            scanf("%d%d",&n,&m); 
            init(); 
            for(int i = 1;i <= n; ++i) scanf("%d%d",&node[i].p[0],&node[i].p[1]); 
            int root = build(1,n,0); 
            for(int i = 1;i <= m; ++i) {
                int opt,a,b; 
                scanf("%d%d%d",&opt,&a,&b);       
                if(opt == 1) {
                    Data k; 
                    k.p[0] = a,k.p[1] = b;        
                    update(root,k,0);   
                    if(i % 300000 == 0) root = build(1,tot,0);   
                }
                if(opt == 2) {
                    ans = inf; 
                    query(root,a,b); 
                    printf("%d
    ",ans); 
                }
            }
            return 0; 
        }     
    };     
    //STL - set
    namespace STL{
        int main(){
            set<int>::iterator s; 
            set<int>p; 
            int n = 10; 
            for(int i = n;i >= 1; --i) p.insert(i); 
            for(s = p.begin();s!=p.end();s++){
                printf("%d
    ",*s);          
            }
            return 0; 
        }
    };   
    //分块 ::                
    namespace Block{
        #define maxn 1000000  
        #define inf 100000000 
        int n,m;
        int arr[maxn],minv[maxn],belong[maxn];
        int block;
        void build(){
            memset(minv,127,sizeof(minv)); 
            scanf("%d",&m);
            block = sqrt(n); 
            for(int i = 1;i <= n; ++i) {
                scanf("%d",&arr[i]); 
                belong[i] = (i - 1) / block + 1; 
                minv[belong[i]] = min(minv[belong[i]],arr[i]); 
            }
            int query(int l,int r){
                int minn = inf; 
                for(int i = l;i <= min(belong[l] * block); ++i) minn=min(minn,arr[i]); 
                if(belong[l] != belong[r]) {
                    for(int i = (belong[r] - 1) * block + 1;i <= r; ++i) 
                        minn = min(minn,arr[i]); 
                }
                for(int i = belong[l] + 1;i < belong[r]; ++i) minn=min(minn,minv[i]); 
                return minn; 
            }
        }T; 
        int main(){
            T.build();
            while(m--){
                int a,b; 
                scanf("%d%d",&a,&b); 
                printf("%d
    ",T.query(a,b)); 
            }
            return 0; 
        }
    }; 
    //CDQ分治 --- 3维LIS
    namespace CDQ{
        #define maxn 500060 
        #define ll long long 
        #define nex (oo = (oo * A) % mod)
        #define setIO(s) freopen(s".in","r",stdin) 
        int n,cnt,fin,ans[maxn]; 
        long long mod,oo = 1,A,H[maxn]; 
        void getmax(int &a,int b){ if(b > a) a = b; }
        struct Node{
            long long x,y,z; 
            int id; 
        }node[maxn],arr[maxn]; 
        int cmpx(Node a,Node b){ 
            if(a.x == b.x && a.y == b.y) return a.z < b.z; 
            if(a.x == b.x) return a.y < b.y; 
            return a.x < b.x;  
        }
        int cmpy(Node a,Node b){
            if(a.x == b.x) return a.y < b.y; 
            return a.x < b.x; 
        }
        int equal(Node a,Node b) {
            return (a.x == b.x && a.y == b.y && a.z == b.z); 
        }
        struct BIT{
            int C[maxn]; 
            int lowbit(int x){
                return x & (-x); 
            }
            void update(int p,int x){
                while(p < maxn){
                    C[p] = max(C[p],x); 
                    p += lowbit(p); 
                }
            }
            int query(int p){
                if(p <= 0) return 0; 
                int ss = 0;
                while(p > 0) {
                    ss = max(ss,C[p]), p -= lowbit(p); 
                }
                return ss; 
            }
            void del(int p){
                while(p < maxn) C[p] = 0,p += lowbit(p); 
            }
        }tree;
        void solve(int l,int r){
            if(l >= r) return ;
            int mid = (l + r) >> 1,tl = l,tr = mid + 1;
            solve(l,mid); 
            sort(arr+l,arr+mid+1,cmpy),sort(arr+mid+1,arr+r+1,cmpy); 
            while(tl <= mid && tr <= r){
                if(arr[tl].y < arr[tr].y){
                    tree.update(arr[tl].z,ans[arr[tl].id]); 
                    ++tl; 
                }
                else {
                    getmax(ans[arr[tr].id],tree.query(arr[tr].z - 1) + 1); 
                    ++tr; 
                }
            }
            for(int i = tr;i <= r; ++i) getmax(ans[arr[i].id],tree.query(arr[i].z-1) + 1); 
            for(int i = l;i <= mid; ++i) tree.del(arr[i].z); 
            sort(arr+mid+1,arr+1+r,cmpx),solve(mid+1,r); 
        }; 
    }; 
    //非旋转 treap
    namespace fhqtreap{
        #define maxn 1000000  
        typedef pair<int,int>par;
        #define mk make_pair
        int n,m,rt,tot; 
        int lz[maxn],val[maxn],key[maxn],rs[maxn],ls[maxn],sz[maxn]; 
        void up(int x){ sz[x]=sz[ls[x]]+sz[rs[x]]+1; }
        void pd(int x){
            if(!x||!lz[x]) return; 
            swap(ls[x],rs[x]),lz[x]^=1;
            if(ls[x]) lz[ls[x]]^=1;
            if(rs[x]) lz[rs[x]]^=1; 
        }
        par split(int x,int k){
            pd(x); 
            if(!k) return mk(0,x); 
            par t1,t2;
            int lson=ls[x],rson=rs[x];
            if(k==sz[ls[x]]) { ls[x]=0,up(x); return mk(lson,x);    }
            else if(k==sz[ls[x]]+1) { rs[x]=0,up(x); return mk(x,rson); }
            else if(k < sz[ls[x]]) {
                t1=split(ls[x],k); 
                ls[x]=t1.second,up(x); 
                return mk(t1.first,x); 
            }
            else {
                t1=split(rs[x],k-sz[ls[x]]-1); 
                rs[x]=t1.first,up(x); 
                return mk(x,t1.second); 
            }
        }
        int merge(int a,int b){
            if(!a||!b) return a+b; 
            pd(a),pd(b); 
            if(key[a]<key[b]){
                ls[b]=merge(a,ls[b]),up(b);
                return b;  
            }
            else{
                rs[a]=merge(rs[a],b),up(a); 
                return a; 
            }
        }
        void print(int x){
            if(!x) return;
            pd(x); 
            print(ls[x]),printf("%d ",val[x]),print(rs[x]); 
        }
        int main(){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;++i) {
                key[++tot]=rand(),val[tot]=i,sz[tot]=1; 
                rt=merge(rt,tot); 
            }
            for(int x,y,i=1;i<=m;++i) {
                scanf("%d%d",&x,&y); 
                par t1=split(rt,y);     
                par t2=split(t1.first,x-1); 
                lz[t2.second]^=1; 
                merge(merge(t2.first,t2.second),t1.second); 
            }    
            print(rt); 
            return 0; 
        }
    }; 
    //可持久treap
    namespace fhqtreap{
        #define maxn 20000000   
        #define ll long long 
        int tot,m,tr;
        int trash[maxn]; 
        int ls[maxn],rs[maxn],rev[maxn],val[maxn],sz[maxn],key[maxn];  
        int root[maxn]; 
        ll sumv[maxn];
        ll lastans;   
        void ini(){
            tr=0; 
            for(int i=1;i<1000000;++i) trash[++tr]=i; 
            tot=1000001; 
        }
        int newnode(){ 
            return tr?trash[tr--]:++tot; 
        }
        int cpy(int p){   
            int x=newnode();     
            sz[x]=sz[p],ls[x]=ls[p],rs[x]=rs[p]; 
            rev[x]=rev[p],val[x]=val[p],key[x]=key[p],sumv[x]=sumv[p]; 
            return x; 
        }
        void up(int x){
            sz[x]=sz[ls[x]]+sz[rs[x]]+1;
            sumv[x]=sumv[ls[x]]+sumv[rs[x]]+(long long)val[x]; 
        }
        int New(int v){
            int p=newnode(); 
            sz[p]=1,ls[p]=rs[p]=0,sumv[p]=val[p]=v,key[p]=rand(),rev[p]=0; 
            return p; 
        }
        void era(int x){
            sz[x]=ls[x]=rs[x]=rev[x]=val[x]=sumv[x]=key[x]=0; 
            trash[++tr]=x; 
        }
        void pd(int x){
            if(!x||!rev[x]) return;     
            if(rev[x]){
                swap(ls[x],rs[x]);
                if(ls[x]) ls[x]=cpy(ls[x]),rev[ls[x]]^=1;
                if(rs[x]) rs[x]=cpy(rs[x]),rev[rs[x]]^=1; 
                rev[x]=0; 
            }
        }
        void split(int x,int k,int &l,int &r){
            if(x){
                pd(x); 
                if(k<=sz[ls[x]]) {
                    r=cpy(x);     
                    split(ls[r],k,l,ls[r]);  
                    up(r); 
                }
                else {
                    l=cpy(x); 
                    split(rs[l],k-sz[ls[l]]-1,rs[l],r);   
                    up(l);  
                }
            }else l=r=0; 
        }
        int mg(int l,int r){
            if(l&&r){
                if(key[l]<key[r]) {
                    pd(r),ls[r]=mg(l,ls[r]),up(r); 
                    return r; 
                }else {
                    pd(l),rs[l]=mg(rs[l],r),up(l); 
                    return l; 
                }
            }else return l+r;     
        }         
        void ins(int &rt,int p,int v){
            int x,y; 
            split(rt,p,x,y);         
            rt=mg(mg(x,New(v)),y);  
        }
        void Del(int &rt,int p){      
            int x,y,z; 
            split(rt,p,x,y),split(x,p-1,x,z),era(z); 
            rt=mg(x,y); 
        }
        void Rev(int &rt,int L,int R){
            int x,y,z; 
            split(rt,R,x,y),split(x,L-1,x,z),rev[z]^=1; 
            rt=mg(mg(x,z),y); 
        }
        void Q(int &rt,int L,int R){
            int x,y,z; 
            split(rt,R,x,y),split(x,L-1,x,z), printf("%lld
    ",(lastans=sumv[z])); 
            rt=mg(mg(x,z),y); 
        }
        int main(){
            ini();
            int n,a=0,b=0; 
            scanf("%d",&n); 
            for(int opt,v,i=1;i<=n;++i){
                scanf("%d%d",&v,&opt); 
                root[i]=root[v]; 
                scanf("%d",&a),a^=lastans; 
                if(opt!=2) scanf("%d",&b),b^=lastans; 
                if(opt==1) ins(root[i],a,b); 
                if(opt==2) Del(root[i],a); 
                if(opt==3) Rev(root[i],a,b); 
                if(opt==4) Q(root[i],a,b); 
            }
            return 0; 
        }
    }; 
    

      

  • 相关阅读:
    写在开篇——过往总结
    线程池原理实现
    MD5加密工具类
    跨域及jsonp
    四种xml的解析方式
    浅析正则表达式—(原理篇)
    用JavaScript添加选择按钮的背景颜色和juqery添加选择按钮的背景色
    怎么用JavaScript实现tab切换
    vue.js2.0:如何搭建开发环境及构建项目
    vscode如何用浏览器预览运行html文件
  • 原文地址:https://www.cnblogs.com/guangheli/p/10656466.html
Copyright © 2020-2023  润新知