shopping spree

The problem of BZOJ 3257 JZOJ 3347 tree

subject

Analysis

Tree dp, let dp[x][i][j]dp[x][i][j]dp[x][i][j] denote the xxx point, whether there are black spots or not, the number of white spots is jjj, if j ≥ 2j\geq 2j ≥ 2, it is regarded as the minimum cost of 2.
Then dp[x][i][j] = ∑ son ∈ I min{dp[son][i ']} + WDP [x] [i] [j] = \ sum {son \ in I} \ min \ {dp[son][i & {x27;] [j & {x27;] \} + WDP [x] [i] [j] = ∑ son ∈ I {min{dp[son][i']} + w

Code

#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
typedef long long ll;
const ll inf=1e14,N=3e5+1;
struct node{int y,w,next;}e[N<<1|1];
int k,ls[N],a[N],n,head,tail; ll dp[N][2][3];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void add(int x,int y,int w){
	e[++k]=(node){y,w,ls[x]}; ls[x]=k;
	e[++k]=(node){x,w,ls[y]}; ls[y]=k;	
}
inline ll min(ll a,ll b){return a<b?a:b;}
signed main(){
	for (rr int t=iut();t;--t){
		k=head=tail=1; memset(ls,0,sizeof(ls));
		n=iut(); rr int stx[n+1],sfa[n+1];
		for (rr int i=1;i<=n;++i) a[i]=iut();
		for (rr int i=1,u,v;i<n;++i)
		    u=iut(),v=iut(),add(u,v,iut());
		stx[1]=sfa[1]=1;
		while (head<=tail){
			rr int x=stx[head],fa=sfa[head++];
			for (rr int i=ls[x];i;i=e[i].next)
			    if (e[i].y!=fa) stx[++tail]=e[i].y,sfa[tail]=x;
		}
		for (rr int h=tail;h;--h){
			rr int x=stx[h],fa=sfa[h];
	        for (rr int p1=0;p1<2;++p1)
	        for (rr int p2=0;p2<3;++p2) dp[x][p1][p2]=inf;
	        dp[x][a[x]==0][a[x]==1]=0;
	        for (rr int i=ls[x];i;i=e[i].next)
	        if (e[i].y!=fa){
		        rr ll f[2][3];
		        for (rr int p1=0;p1<2;++p1)
		        for (rr int p2=0;p2<3;++p2) f[p1][p2]=inf;
				for (rr int p1=0;p1<2;++p1)
				for (rr int p2=0;p2<3;++p2) if (dp[x][p1][p2]!=inf)
				for (rr int p3=0;p3<2;++p3)
				for (rr int j=0;j<3;++j) if (dp[e[i].y][p3][j]!=inf){
			        rr int z1=p1+p3>=1,z2=min(p2+j,2);
					f[z1][z2]=min(f[z1][z2],dp[x][p1][p2]+dp[e[i].y][p3][j]);
			        if (!p3||j<2) f[p1][p2]=min(f[p1][p2],dp[x][p1][p2]+dp[e[i].y][p3][j]+e[i].w);
		        }
				memcpy(dp[x],f,sizeof(f));
		    }
		}
		printf("%lld\n",min(min(min(dp[1][0][0],dp[1][0][1]),min(dp[1][0][2],dp[1][1][0])),dp[1][1][1]));
    }
	return 0;
}

BZOJ 3258 JZOJ 3348 secret mission

subject

Analysis

This is a problem of finding the minimum cut. For the second question, is the minimum cut unique? If and only if the two ends of the cut edge belong to the starting point or the end point, use tarjan to solve it.

Code

#include <cstdio>
#include <cctype>
#include <cstring>
#include <queue>
#define cle(TEMP,_T) memset(TEMP,_T,sizeof(TEMP))
#define min(a,b) ((a)<(b)?(a):(b))
#define rr register
using namespace std;
typedef unsigned uit;
const uit inf=4e9+101;
struct node{uit y,w,next;}e[8011],E[8011]; bool v[401]; long long dis[401];
uit k1,k2,ls[401],hs[401],dfn[401],low[401],stack[401],a[401],dcc[401],s,t,n,m,top,DCC,ans,flag; 
inline signed iut(){
	rr uit ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void Add(uit x,uit y,uit w){
	E[++k2]=(node){y,w,hs[x]},hs[x]=k2;
	E[++k2]=(node){x,w,hs[y]},hs[y]=k2;
}
inline void add(uit x,uit y,uit w){
	e[++k1]=(node){y,w,ls[x]},ls[x]=k1;
	e[++k1]=(node){x,0,ls[y]},ls[y]=k1;
}
inline void spfa(){
	for (rr uit i=1;i<=n;++i) dis[i]=1e14,v[i]=0;
	dis[1]=0,v[1]=1; rr deque<uit>q; q.push_front(1);
	while (q.size()){
		rr uit x=q.front(); q.pop_front();
		for (rr uit i=hs[x];i;i=E[i].next)
		if (dis[E[i].y]>dis[x]+E[i].w){
			dis[E[i].y]=dis[x]+E[i].w;
			if (!v[E[i].y]){
				v[E[i].y]=1;
				if (q.size()&&dis[E[i].y]<dis[q.front()]) q.push_front(E[i].y);
				    else q.push_back(E[i].y);
			}
		}
		v[x]=0;
	}
}
inline void Dfs(uit x){
	if (v[x]) return; v[x]=1;
	for (rr uit i=hs[x];i;i=E[i].next)
	if (dis[x]==dis[E[i].y]+E[i].w)
	    add(E[i].y,x,min(a[x],a[E[i].y])),Dfs(E[i].y);
}
inline signed bfs(uit s){
    for (rr uit i=1;i<=t;++i) dis[i]=0;
    queue<uit>q; q.push(s); dis[s]=1;
    while (q.size()){
        rr uit x=q.front(); q.pop();
        for (rr uit i=ls[x];i;i=e[i].next)
        if (e[i].w>0&&!dis[e[i].y]){
            dis[e[i].y]=dis[x]+1;
            if (e[i].y==t) return 1;
            q.push(e[i].y);
        }
    }
    return 0;
}
inline signed dfs(uit x,uit now){
    if (x==t||!now) return now;
    rr uit rest=0,f;
    for (rr uit i=ls[x];i;i=e[i].next)
    if (e[i].w>0&&dis[e[i].y]==dis[x]+1){
        rest+=(f=dfs(e[i].y,min(now-rest,e[i].w)));
        e[i].w-=f; e[i^1].w+=f;
        if (now==rest) return rest;
    }
    if (!rest) dis[x]=0;
    return rest;
}
inline signed dinic(){
	rr uit ans=0;
	while (bfs(s)) ans+=dfs(s,inf);
	return ans;
}
inline void tarjan(uit x){
	dfn[x]=low[x]=++dfn[0],stack[++top]=x;
	for (rr uit i=ls[x];i;i=e[i].next)
	if (e[i].w){
		if (!dfn[e[i].y]) tarjan(e[i].y),low[x]=min(low[x],low[e[i].y]);
		    else if (!dcc[e[i].y]) low[x]=min(low[x],dfn[e[i].y]);
	}
	if (dfn[x]==low[x]){
	    ++DCC;
		for (uit y;y!=x;--top) dcc[y=stack[top]]=DCC;
	}	
}
signed main(){
	for (rr uit T=iut();T;--T){
		cle(hs,0),cle(ls,0),cle(dfn,0),cle(low,0),cle(dcc,0),
		n=iut(),m=iut(),k1=k2=1,flag=DCC=top=0;
		for (rr uit i=1;i<n;++i) a[i]=iut(); a[n]=inf;
		for (rr uit i=1,x,y;i<=m;++i) x=iut(),y=iut(),Add(x,y,iut());
		spfa(),s=1,t=n,Dfs(n),ans=dinic();
		for (rr uit i=1;i<=n;++i) if (!dfn[i]) tarjan(i);
		for (rr uit i=2;i<=k1;i+=2) if (!e[i].w){
			if (dcc[e[i].y]!=dcc[e[i^1].y]&&!(dcc[e[i^1].y]==dcc[1]&&dcc[e[i].y]==dcc[n])) flag=1;
			if (dcc[e[i^1].y]==dcc[1]&&dcc[e[i].y]==dcc[n]&&a[e[i].y]==a[e[i^1].y]) flag=1;
		}
		!flag?printf("Yes "):printf("No "); printf("%u\n",ans); 
	}
	return 0;
}

JZOJ 3379 query

subject

For multiple groups of queries, the number of 5 intervals at most is thrown into multiset, and the kkk is small.

Analysis

The chairman's tree is naked, and there is not much explanation

Code

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=200101;
int a[N],b[N],rt[N],L[5],R[5],tot,n,q,m;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
struct Chair{
    int w[N*20],ls[N*20],rs[N*20],cnt;
    inline void build(int &rt,int l,int r){
        w[rt=++cnt]=0; rr int mid=(l+r)>>1;
        if (l<r) build(ls[rt],l,mid),build(rs[rt],mid+1,r); 
    }
    inline void update(int &rt,int l,int r,int k){
        rr int trt=++cnt,mid=(l+r)>>1;
        ls[trt]=ls[rt],rs[trt]=rs[rt],w[trt]=w[rt]+1,rt=trt;
        if (l==r) return;
        k<=mid?update(ls[trt],l,mid,k):update(rs[trt],mid+1,r,k);
    }
    inline signed query(int l,int r,int k){
    	if (l==r) return l;
    	rr int x=0,mid=(l+r)>>1;
    	for (rr int i=0;i<tot;++i) x+=w[ls[R[i]]]-w[ls[L[i]]];
    	for (rr int i=0;i<tot;++i)
    	    x>=k?(L[i]=ls[L[i]],R[i]=ls[R[i]]):(L[i]=rs[L[i]],R[i]=rs[R[i]]);
    	return x>=k?query(l,mid,k):query(mid+1,r,k-x);
    } 
}Tre;
signed main(){
	n=iut(); q=iut();
    for (rr int i=1;i<=n;++i) b[i]=a[i]=iut();
    sort(b+1,b+1+n); m=unique(b+1,b+1+n)-b-1;
    Tre.cnt=0; Tre.build(rt[0],1,m);
    for (rr int i=1;i<=n;++i)
        Tre.update(rt[i]=rt[i-1],1,m,lower_bound(b+1,b+1+m,a[i])-b);
    while (q--){
    	tot=iut(); rr int k=iut();
    	for (rr int i=0;i<tot;++i) L[i]=rt[iut()-1],R[i]=rt[iut()];
    	print(b[Tre.query(1,m,k)]),putchar(10);
    }
    return 0;
}