Loading

noip模拟17

A. 世界线

又是一个看性质决定走向的题目.
打表即可发现就是每个点能到达的点数之和减去已经有的边.
发现直接使用图的遍历算法复杂度并不是很优秀.
于是考虑使用\(bitset\)优化,把每个点的信息传递给所有可以到达\(ta\)的点.
然后我们可以考虑一个垃圾回收算法.
想法来自 Yubai.
可以选择将已经被榨干贡献的点的空间留给别的点.
这个算法很常用,而以后我也使用这个想法在考场上\(A\)掉了题.

不愧是Yubai.

A_code
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define re register ll
#define lf double
#define lb lower_bound
#define mp make_pair
const ll N=6e4+50;
inline void read(ll &ss)
{
	ss=0; bool cit=0; char ch;
	while(!isdigit(ch=getchar())) if(ch=='-') cit=1;
	while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
	if(cit) ss=-ss;
}
bitset<N> s[N>>1];
deque<ll> que;
ll m,n,ts,sum,edge,tot;
ll head[N],d[N],ans[N],use[N],with[N];
bool vis[N];
struct I { ll u,v,nxt; } a[N*8];
inline void add(ll u,ll v)
{
	a[++ts].u=u;
	a[ts].v=v;
	a[ts].nxt=head[u];
	head[u]=ts;
}
signed main()
{
	read(n); read(m);
	ll u,v,w;
	for(re i=1;i<=m;i++)
	{
		read(u); read(v);
		add(v,u); d[u]++;
	}
	for(ll i=1;i<=n;i++) 
	{
		if(d[i]==0)
		{
			que.push_back(i);
			use[i]=++edge;
			with[edge]=use[i];
		}
	}
	ll now;
	while(que.size())
	{
		ll now=que.front(); que.pop_front();
		ans[now]=s[use[now]].count();
		//cout<<"now:"<<now<<" skr\n";
		s[use[now]].set(now,1);
		for(ll i=head[now];i;i=a[i].nxt)
		{
			if(--d[a[i].v]==0) 
			{
				que.push_back(a[i].v);
			}
			if(use[a[i].v]==0)
			{
				if(tot) use[a[i].v]=with[tot--];
				else use[a[i].v]=++edge;
			//	cout<<"a[i].v:"<<a[i].v<<" "<<use[a[i].v]<<" der\n";
			}
			s[use[a[i].v]]|=s[use[now]];
		}
		with[++tot]=use[now]; s[use[now]].reset();
	}
	ll alls=0;
	for(re i=1;i<=n;i++) 
	{
//		cout<<ans[i]<<" ";
		alls+=ans[i];
	}
	printf("%d",alls-m);
}

B. 时间机器

一个显然的贪心.我考场上又写挂了..
自此学会要灵活使用\(STL\).

B_code
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define re register ll
#define lf double
#define lb lower_bound
#define mp make_pair
const ll N=5e5+50;
inline void read(ll &ss)
{
	ss=0; bool cit=0; char ch;
	while(!isdigit(ch=getchar())) if(ch=='-') cit=1;
	while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
	if(cit) ss=-ss;
}
ll ts,m,n,ans;
ll lsh[N*10];
struct I 
{ 
	ll l,r,cnt; 
	I(){} I(ll a,ll b,ll c){l=a,r=b,cnt=c;}
} a[N],b[N];
bool comp(I i,I j){ return i.l!=j.l ? i.l<j.l : i.r<j.r ; }
multiset<I> s;
bool operator < (const I &i,const I &j) { return i.r<j.r; }
signed main()
{
//	freopen("0.in","r",stdin);
//	freopen("out","w",stdout);
	read(ts);
	while(ts--)
	{
		read(n); read(m);
		ll gets=0,sum=0,alls=0,ans=0;
		s.clear();
		for(re i=1;i<=n;i++) 
		{
			read(a[i].l); read(a[i].r); read(a[i].cnt);
			lsh[++alls]=a[i].l; lsh[++alls]=a[i].r;
			sum+=a[i].cnt;
		}
		for(re i=1;i<=m;i++)
		{
			read(b[i].l); read(b[i].r); read(b[i].cnt);
			lsh[++alls]=b[i].l; lsh[++alls]=b[i].r;
		}
		sort(lsh+1,lsh+1+alls);
		alls=unique(lsh+1,lsh+1+alls)-lsh-1;
		for(ll i=1;i<=n;i++) 
		{
			a[i].l=lb(lsh+1,lsh+1+alls,a[i].l)-lsh;
			a[i].r=lb(lsh+1,lsh+1+alls,a[i].r)-lsh;
		}
		for(ll i=1;i<=m;i++)
		{
			b[i].l=lb(lsh+1,lsh+1+alls,b[i].l)-lsh;
			b[i].r=lb(lsh+1,lsh+1+alls,b[i].r)-lsh;
		}
		sort(a+1,a+1+n,comp); sort(b+1,b+1+m,comp);
		I temp=(I){0,1e9,0};
		s.insert(temp);
		multiset<I>::iterator it;
		for(re i=1,j=1;i<=n;i++)
		{	
			//it=s.begin();
			//while(*it.r<a[i].r) it++;
			while(j<=m and b[j].l<=a[i].l)
			{
				s.insert(b[j]);
				j++;
			}
			while(a[i].cnt && !s.empty())
			{
				it=s.lower_bound(a[i]);
				//cout<<(it->r)<<"\n";
				if(it->r==1e9){ans=1; break;}
				I tmp=I(it->l,it->r,it->cnt);
				s.erase(it);
				if(tmp.cnt<=a[i].cnt) 
				{
					a[i].cnt-=tmp.cnt;
					tmp.cnt=0;
				}
				else
				{
					tmp.cnt-=a[i].cnt;
					a[i].cnt=0;
					s.insert(tmp);
				}
			}
			if(a[i].cnt) ans=1;
			if(ans) break;
		}
		if(ans==1) printf("No\n");
		else printf("Yes\n");
	}	
	return 0;
}

C. weight

image
题解说的很清楚.

C_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define re register ll 
#define lf double
#define mp make_pair
const ll N=(7e4+50)*2;
const ll M=1e5+50;
inline void read(ll &ss)
{
	ss=0; bool cit=0; char ch;
	while(!isdigit(ch=getchar())) if(ch=='-') cit=1;
	while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
	if(cit) ss=-ss;
}
ll n,m,sp,ts,cnt;
ll head[N],fa[N],head2[N],dfn[N],top[N],siz[N],rk[N],dep[N],son[N];
ll weight[N],ans[N];
bool inv[M],vis[N];
struct I { ll u,v,w,id,nxt; } a[M*2],b[N*2];
struct II { ll w,l,r,mx,mn,lazy; } tr[N*5];
inline void add(ll u,ll v,ll w)
{
	a[++ts].u=u;
	a[ts].v=v;
	a[ts].w=w;
	a[ts].id=ts;
}
inline void add2(ll u,ll v,ll w)
{
	b[++ts].u=u;
	b[ts].v=v;
	b[ts].w=w;
	b[ts].nxt=head2[u];
	head2[u]=ts;
}
ll find(ll x){ return x==fa[x] ? x : (fa[x]=find(fa[x])) ; }
inline bool comp(I i,I j){ return i.w<j.w; }
void Kruskal()
{
	ll u,v,w; ts=0;
	for(re i=1;i<=n;i++) fa[i]=i;
	sort(a+1,a+1+m,comp);
	for(ll i=1;i<=m;i++)
	{
		u=find(a[i].u); v=find(a[i].v);
		if(u==v) continue;
		fa[v]=u; inv[i]=1;
		add2(a[i].u,a[i].v,a[i].w);
		add2(a[i].v,a[i].u,a[i].w);
	}
	for(re i=1;i<=n;i++)
	{
		u=find(i);
		if(u==fa[1]) vis[i]=1;
	}
	memset(fa,0,sizeof fa);
	return ;
}
void spread(ll x)
{
	if(tr[x].lazy!=1e10+50)
	{
		tr[x<<1].mn=min(tr[x].lazy,tr[x<<1].mn);
		tr[x<<1|1].mn=min(tr[x].lazy,tr[x<<1|1].mn);
		tr[x<<1].lazy=min(tr[x].lazy,tr[x<<1].lazy);
		tr[x<<1|1].lazy=min(tr[x].lazy,tr[x<<1|1].lazy);
		tr[x].lazy=1e10+50;
	}
	return ;
}
void pushup(ll x)
{
	tr[x].w=max(tr[x<<1].w,tr[x<<1|1].w);
	return ;	
}
void dfs1(ll now,ll dad,ll depth)
{
	fa[now]=dad; siz[now]=1; dep[now]=depth;
	for(re i=head2[now];i;i=b[i].nxt)
	{
		if(b[i].v==dad) continue;
		weight[b[i].v]=b[i].w;
		dfs1(b[i].v,now,depth+1);
		siz[now]+=siz[b[i].v];
		if(siz[b[i].v]>siz[son[now]])
		{
			son[now]=b[i].v;
		}
	}
}
void dfs2(ll now,ll high)
{
	dfn[now]=++cnt;  rk[cnt]=now;
	top[now]=high; 
	if(!son[now]) return ;
	dfs2(son[now],high);
	for(re i=head2[now];i;i=b[i].nxt)	
	{
		if(b[i].v==son[now] or b[i].v==fa[now]) continue;
		dfs2(b[i].v,b[i].v);
	}
	return ;
}
void build(ll x,ll l,ll r)
{
	tr[x].l=l; tr[x].r=r; tr[x].lazy=1e10+50;
	if(tr[x].l==tr[x].r) 
	{
		tr[x].w=weight[rk[l]];
		tr[x].mn=1e10+50;
		return ;
	}
	ll mid=(l+r)>>1;
	build(x<<1,l,mid); build(x<<1|1,mid+1,r);
	pushup(x);
}
void update(ll x,ll ql,ll qr,ll val)
{
	if(tr[x].l>=ql and tr[x].r<=qr)
	{
		tr[x].mn=min(tr[x].mn,val);
		tr[x].lazy=min(tr[x].lazy,val);
		return ;
	}
	spread(x);
	ll mid=(tr[x].l+tr[x].r)>>1;
	if(ql<=mid) update(x<<1,ql,qr,val);
	if(qr>=mid+1) update(x<<1|1,ql,qr,val);
	pushup(x);
	return ;
}
ll query_max(ll x,ll ql,ll qr)
{
	if(ql>qr) return 0;
	if(tr[x].l>=ql and tr[x].r<=qr)
	{
		return tr[x].w;
	}
	spread(x);
	ll temp=-1;
	ll mid=(tr[x].l+tr[x].r)>>1;
	if(ql<=mid) temp=max(temp,query_max(x<<1,ql,qr));
	if(qr>=mid+1) temp=max(temp,query_max(x<<1|1,ql,qr));
	return temp;
}
ll query(ll x,ll pos)
{
	if(tr[x].l==tr[x].r) return tr[x].mn;
	spread(x);
	ll mid=(tr[x].r+tr[x].l)>>1;
	if(pos<=mid) return query(x<<1,pos);
	else return query(x<<1|1,pos);
}
ll QMAX(ll x,ll y)
{
	ll ans=-1;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=max(ans,query_max(1,dfn[top[x]],dfn[x]));
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	if(x!=y) ans=max(ans,query_max(1,dfn[x]+1,dfn[y]));
	return ans;
}
void CHANGE(ll x,ll y,ll val)
{
//	cout<<x<<" "<<y<<" "<<val<<'\n';
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,dfn[top[x]],dfn[x],val);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	if(x!=y) update(1,dfn[x]+1,dfn[y],val);
	return ;
}
void Work()
{
	for(re i=1;i<=m;i++)
	{	
		if(vis[a[i].u]==0 and vis[a[i].v]==0) 
		{
			ans[a[i].id]=0; continue;
		}
		if(!inv[i])
		{
			ans[a[i].id]=QMAX(a[i].u,a[i].v)-1;
			CHANGE(a[i].u,a[i].v,a[i].w);
		}
	}
	for(re i=1;i<=m;i++)
	{
		if(inv[i] and vis[a[i].u] and vis[a[i].v])
		{
			ans[a[i].id]=query(1,max(dfn[a[i].v],dfn[a[i].u]))-1;
		}
	}
	return ;
}
signed main()
{
//	freopen("0.in","r",stdin);
//	freopen("out","w",stdout);
	read(n); read(m); read(sp);
	ll u,v,w;
	for(re i=1;i<=m;i++)
	{
		read(u); read(v); read(w);
		add(u,v,w);
	}
	Kruskal(); 
	dfs1(1,0,1); dfs2(1,1);
	build(1,1,cnt);
	Work();	
	for(re i=1;i<=m;i++)
	{
		if(ans[i]==1e10+49) ans[i]=-1;
		printf("%lld ",ans[i]);
	}
	return 0;
}
posted @ 2021-08-05 19:52  AaMuXiiiiii  阅读(29)  评论(0编辑  收藏  举报