省选模板大杂烩
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\n",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\n",*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\n",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\n",(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;
}
};

浙公网安备 33010602011771号