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; } };