noip模拟49(待补)

A. reverse

可以发现每个点可以到达的点都是固定的.
所以如果给每个点向 \(ta\) 所能到达的点都连一条边,
那就是求每个点的最浅深度了.
复杂度\(O(n^2)\).可以卡常\(A\)掉.
正解给出了 \(set\)\(O(nlogn)\)做法.
这里有一个链表\(O(n)\)做法.(不是我的想法.)
每个点的答案一定是在第一次被遍历时的答案.
所以可以剪掉很多枝.

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll int
	#define ull unsigned ll
	#define re register ll 
	#define lf double
	#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+21;

ll m,n,s,st;
ll col[N],R[N],Q[N];
signed main(){
	n=read(),s=read(),m=read(); ll l,r;
	for(re i=1;i<=n;i++) col[i]=n+1,R[i]=i+2; 
	col[st=read()]=0; Q[1]=st;
	for(re i=1;i<=m;i++) col[read()]=-1;
	for(re h=1,t=1;h<=t;h++){
		st=max(1,Q[h]-s+1),l=st+st+s-1-Q[h],
		st=min(n-s+1,Q[h]),r=st+st+s-1-Q[h];
		for(re i=l;i<=r;i=R[i]) if(col[i]>col[Q[h]]+1) col[i]=col[Q[h]]+1,Q[++t]=i;
		for(re i=l;i<=r;i=st){ st=R[i],R[i]=max(R[i],r),i=st; }
	}
	for(re i=1;i<=n;i++){
		if(col[i]>n) cout<<-1<<‘ ‘;
		else cout<<col[i]<<‘ ‘;
	}
	exit(0);
}

B. Silhouette

很显然是要容斥一下啊,但是并不知道如何写.
虽然都是在容斥的角度思考,但是自己的想法和正解还是有很大出入.
发现了变换顺序也不会影响答案的性质,但是没有想到接下来的做法.
一定要灵活运用自己发现的性质,但如果想了很久也没能有成果大概率就不会是这个角度吧.
这个题目zero4338画了图,讲得很清晰..%%%
这里就不再赘述了.

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define lf double
	#define re register ll 
	#define ull unsigned ll
	#define mp make_pair
	#define lb lower_bound 
	#define ub upper_bound 
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	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+21,mod=1e9+7;

ll n,m,ans=1;
ll ha[N],hb[N],frc[N];
inline ll ksm(ll a,ll b,ll c){
	a%=c; ll res=1;
	while(b){
		if(b&1) res=(res*a)%c;
		a=(a*a)%c,b>>=1;
	}
	return res%c;
}
inline ll C(ll a,ll b){
	if(a>b) return 0;
	return frc[b]*ksm(frc[b-a],mod-2,mod)%mod*ksm(frc[a],mod-2,mod)%mod;
}
inline ll calc(ll A,ll B,ll a,ll b,ll w){
	ll res,ret,sum=0;
	for(re i=0;i<=a;i++){
		res=C(i,a),ret=ksm(w,i,mod)*((ksm(w+1,A-i,mod)-ksm(w,A-i,mod)+mod)%mod)%mod,
		res=(res*ksm(ret,b,mod))%mod,ret=ksm(ksm(w,i,mod)*ksm(w+1,a-i,mod),B-b,mod),
		res=res*ret%mod*((i&1) ? -1 : 1),sum=(sum+res+mod)%mod;
	}
	return sum%mod;
}
signed main(){
	n=read(),frc[0]=1; ll w,a,b,tmp,temp;
	for(ll i=1;i<=n;i++) frc[i]=frc[i-1]*i%mod;
	for(re i=1;i<=n;i++) ha[i]=read(); for(re i=1;i<=n;i++) hb[i]=read();
	sort(ha+1,ha+1+n),sort(hb+1,hb+1+n); ll p1=1,p2=1;
	if(ha[n]!=hb[n]) puts("0"),exit(0);
	while(p1<=n or p2<=n){
		w=min(ha[p1],hb[p2]),a=0,b=0;
		while(p1<=n and ha[p1]==w) p1++,a++; while(p2<=n and hb[p2]==w) p2++,b++;
		ans=ans*calc(n-p1+a+1,n-p2+b+1,a,b,w)%mod;
	}	
	printf("%lld\n",ans);
	exit(0);
}

C. Seat

noip模拟49(待补)

上一篇:python动态打印进度条


下一篇:vimrc配置文件