1. 程式人生 > 其它 >noip模擬43(待補)

noip模擬43(待補)

A. 第一題

考場上打得線段樹合併\(+\)貪心假了..
貪心應該是正解,但是\(dp\)也可做..
想著線段樹合併時間複雜度可以稍微小一點.
於是放棄了每次使用\(set\)維護,但是其實也能過.
結果\(Vector\)暴力掃\(+\)排序維護也能\(A\).
一般的話,如果是二叉樹,複雜度為\(O(nlogn)\),但是鏈的話可以卡成\(O(n)\).

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define re register ll 
	#define lf double
	#define lbt(x) (x&(-x))
	#define lb lower_bound 
	#define ub upper_bound 
	#define mp make_pair
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	inline ll read()
	{
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=1e5+51;

ll m,n,ts,ans;
ll head[N],rt[N<<6];
vector<ll> vec[N];
struct I { ll u,v,nxt; } e[N<<1];
inline void add(ll u,ll v){
	e[++ts].u=u,e[ts].v=v,e[ts].nxt=head[u];
	head[u]=ts;
}
inline bool comp(ll i,ll j){ return i>j; }
void dfs(ll now,ll dad,ll dep){
	ll flag=1;
	for(re i=head[now];i;i=e[i].nxt){
		if(e[i].v==dad) continue;
		flag=0; dfs(e[i].v,now,dep+1);
		if(vec[now].size()<vec[e[i].v].size()) swap(vec[e[i].v],vec[now]);
		for(auto j : vec[e[i].v]) vec[now].push_back(j);
	}
	if(flag){
		vec[now].push_back(dep); 
		ans+=dep;
		return ;
	}
//	cout<<"Now:"<<now<<" "<<ans<<'\n';
//	for(auto i : vec[now]) cout<<i<<" ";
//	cout<<'\n';
	sort(vec[now].begin(),vec[now].end(),comp);
	if(vec[now].size())
	for(ll i=vec[now].size()-1;i>=1;--i){
		if(vec[now][i]>=2*dep) break;
		ans+=vec[now][i]-2*dep;
		flag++;
	}
	while((flag--) and vec[now].size()){
		vec[now].pop_back();
	}
	return ;
}
signed main(){
	n=read(); ll u,v;
	if(n==1){ cout<<0; return 0; }
	for(re i=2;i<=n;i++) u=read(),v=read(),add(u,v),add(v,u);
	dfs(1,0,0);
	printf("%lld\n",ans);
	return 0;
}

B. 第二題

沒有看到單調性,直接掛了.
二分+\(Spfa\)亂跑就行..
每次將所有的點都壓入佇列,每列舉到一個點,然後就更新周圍的六個就可以..
資料依舊過水,這套題的資料我真的沒話說了.
複雜度 \(O(\)玄學\()\)

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define re register ll 
	#define lf double
	#define lbt(x) (x&(-x))
	#define lb lower_bound 
	#define ub upper_bound 
	#define mp make_pair
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	inline ll read()
	{
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=1e5+51;

ll m,n,t,tot,ts;
ll val[N],head[N],vis[N];
map<pair<ll,ll>,ll> map1;
struct I { ll w; } p[N];
struct II { ll u,v,nxt; } e[N<<6];
inline void add(ll u,ll v){
	e[++ts].u=u,e[ts].v=v,e[ts].nxt=head[u],
	head[u]=ts;
}
queue<ll> que;
inline bool Spfa(ll x){
	for(ll i=1;i<=tot;++i){
		val[i]=p[i].w,vis[i]=1;
		que.push(i);
	}
	ll now,res=0;
	while(que.size()){
		now=que.front(); que.pop();
		for(re i=head[now];i;i=e[i].nxt){
			if(val[e[i].v]-val[now]>x){
				res+=val[e[i].v]-x-val[now],val[now]+=val[e[i].v]-x-val[now];
			}
		}
		for(re i=head[now];i;i=e[i].nxt){
			if(val[now]-val[e[i].v]>x){	
				res+=val[now]-x-val[e[i].v],val[e[i].v]+=val[now]-x-val[e[i].v];
				if(!vis[e[i].v]) que.push(e[i].v);
				vis[e[i].v]=1;
			}
		}
		vis[now]=0;
	}
//	cout<<x<<" "<<res<<endl;
	return res<=t;
}
inline void Work(){
	ll l=0,r=1e12,res=r,mid;
	while(l<=r){
		mid=(l+r)>>1;
		if(Spfa(mid)) r=mid-1,res=mid;
		else l=mid+1;
	}
	printf("%lld",res);
	return ;
}
signed main(){
	n=read(),m=read(),t=read(); ll x,y,temp;
	for(ll i=1;i<=n;++i)
		for(ll j=1;j<=m;++j)
			p[++tot].w=read(),map1[mp(i,j)]=tot;
	for(ll i=1;i<=n;++i){
		for(ll j=1;j<=m;++j){
			if(j>1) add(map1[mp(i,j)],map1[mp(i,j-1)]);
			if(j<m) add(map1[mp(i,j)],map1[mp(i,j+1)]);
			if(i>1) add(map1[mp(i,j)],map1[mp(i-1,j)]);
			if(i>1 and j<m) add(map1[mp(i,j)],map1[mp(i-1,j+1)]);
			if(i<n and j>1) add(map1[mp(i,j)],map1[mp(i+1,j-1)]);
			if(i<n) add(map1[mp(i,j)],map1[mp(i+1,j)]);
		}
	}
	Work();
	return 0;
}