Loading

noip模拟4

A. 随

B. 单

这道题是一道树形动态规划..
有用到换根和前缀和的思想..
上次考试就有树规,可惜我考完试之后自以为是..只打了高斯消元..
结果这次还是用的高斯消元 —— 40 pts —— RE
希望自己的考场应对能力可以强亿点点..

B_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define lf double
#define re register ll
#define le strlen
const ll N=1000050;
const ll MAXN=500000;
const lf eps=1e-8;
inline void read(ll &ss)
{
	ss=0;
	ll cit=0;
	char ch;
	ch=getchar();
	while((ch>'9') or (ch<'0'))
	{
		if(ch=='-') cit=1;
		ch=getchar();
	}
	while((ch<='9') and (ch>='0'))
	{
		ss=(ss<<3)+(ss<<1)+(ch^48);
		ch=getchar();
	}
	if(cit) ss=-ss;
}
ll n;
ll m;
ll ts;
ll alls;
ll crit;
ll from,arrival;
ll ta[N+50];
ll tb[N+50];
ll f[N+50];
ll sum[N+50];
ll vis[N+50];
struct Single
{
	ll u;
	ll v;
	ll w;
	ll nxt;
}a[N];
inline void add(ll u,ll v)
{
	a[++ts].u=u;
	a[ts].v=v;
	a[ts].nxt=f[u];
	f[u]=ts;
}
ll lowdfs(ll now,ll depth)
{
	tb[1]+=ta[now]*depth;
	sum[now]=ta[now];
	vis[now]=1;
	for(re i=f[now];i;i=a[i].nxt)
	{		
		if(!vis[a[i].v]) sum[now]+=lowdfs(a[i].v,depth+1);
	}
	return sum[now];
}//A1
void moredfs(ll now,ll dad)
{
	if(dad!=0) tb[now]=tb[dad]+sum[1]-sum[now]*2;
	vis[now]=1;
	for(re i=f[now];i;i=a[i].nxt)
	{
		if(!vis[a[i].v]) moredfs(a[i].v,now);
	}
}//A2
void dfsmoreover(ll now,ll dad)
{
	if(dad!=0) sum[1]+=tb[now]-tb[dad];
	vis[now]=1;
	for(re i=f[now];i;i=a[i].nxt)
	{
		if(!vis[a[i].v]) dfsmoreover(a[i].v,now);
	}
}//B1
void dfsagain(ll now,ll dad)
{
	if(dad!=0) sum[now]=(sum[1]-tb[now]+tb[dad])/2;
	vis[now]=1;
	for(re i=f[now];i;i=a[i].nxt)
	{
		if(!vis[a[i].v]) dfsagain(a[i].v,now);
	}
}//B2
ll dfs(ll now)
{
	ta[now]=sum[now];
	vis[now]=1;
	for(re i=f[now];i;i=a[i].nxt)
	{
		if(!vis[a[i].v]) ta[now]-=dfs(a[i].v);
	}
	return sum[now];
}//B3
inline void Worka()
{
	for(re i=1;i<=n;++i)
	{
		read(ta[i]);
	}
	memset(vis,0,sizeof(vis));
	lowdfs(1,0);
	memset(vis,0,sizeof(vis));
	moredfs(1,0);
	for(re i=1;i<=n;i++)
	{
		printf("%lld ",tb[i]);
	}
	printf("\n");
	return ;
}
inline void Workb()
{
	for(re i=1;i<=n;++i)
	{
		read(tb[i]);
	}
	memset(vis,0,sizeof(vis));
	sum[1]=2*tb[1];
	dfsmoreover(1,0);
	sum[1]=sum[1]/(n-1);
	memset(vis,0,sizeof(vis));
	dfsagain(1,0);
	memset(vis,0,sizeof(vis));
	dfs(1);
	for(re i=1;i<=n;++i)
	{
		printf("%lld ",ta[i]);
	}
	printf("\n");
	return ;
}
signed main()
{
	read(alls);
	while(alls)
	{
		alls--;
		memset(ta,0,sizeof(ta));
		memset(tb,0,sizeof(tb));
		memset(sum,0,sizeof(sum));
		memset(f,0,sizeof(f));
		read(n);
		for(re i=1;i<=n-1;++i)
		{	
			read(from);
			read(arrival);
			add(from,arrival);
			add(arrival,from);
		}
		read(crit);
		if(crit==0) Worka();
		else Workb();
	}
	return 0;
}

C. 题

卡特兰数板子

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#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) memset(y,x,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 mod=1e9+7;
const ll N=2e5+51;

ll m,n,type,ans;
ll inv[N],fct[N];
ll f[N];
inline ll ksm(ll a,ll b,ll c){
	a%=c; ll temp=1;
	while(b){
		if(b&1) temp=(temp*a)%c;
		a=(a*a)%c; b>>=1;
	}
	return temp%c;
}
inline void Pre(){
	fct[0]=1; inv[0]=1;
	for(re i=1;i<=(n<<1);i++){
		fct[i]=fct[i-1]*i%mod;
		inv[i]=ksm(fct[i],mod-2,mod);
	}
	return ;
}
inline ll C(ll i,ll j){
	if(j>i) return 1;
	if(j<0) return 1;
	return (fct[i]*inv[j])%mod*inv[i-j]%mod;
}
inline ll Cat(ll i){
	if(i<0) return 0;
	if(i==0) return 1;
	return (C(i<<1,i)-C(i<<1,i-1)+mod)%mod;
}
inline void Work_Zero(){	
	for(re i=0;i<=n;i+=2){
		(ans+=C(n,i)*C(i,i>>1)%mod*C((n-i),(n-i)>>1)%mod)%=mod;
	}
	printf("%lld",ans%mod);
}
inline void Work_One(){
	ans=Cat(n>>1);
	printf("%lld",ans%mod);
}
inline void Work_Two(){
	f[0]=1;
	for(re i=2;i<=n;i+=2){
		for(re j=2;j<=i;j+=2){
			(f[i]+=(((f[i-j]*Cat((j>>1)-1))%mod)<<2)%mod)%=mod;
		}
	}
	printf("%lld",f[n]%mod);
}
inline void Work_Three(){
	for(re i=0;i<=n;i+=2)
		(ans+=C(n,i)*Cat(i>>1)%mod*Cat((n-i)>>1)%mod)%=mod;
	printf("%lld",ans%mod);
}
signed main(){
	n=read(); type=read();
	if(n&1){ puts("0"); return 0; }
	Pre();
	if(type==0) Work_Zero();
	if(type==1) Work_One();
	if(type==2) Work_Two();
	if(type==3) Work_Three();
	return 0;
}

D. 大佬

调了很久,在此感谢 Varuxn 大佬对于错误的指出..
学会了 map 和 pair 的一些重要方法..
在这里写下一些值得注意的点..

  1. 无论是 dfs 还是 bfs,需要将最初的状态处理好..
    不要兜兜转转回到起点..最后导致 WA 或者 TLE ..
    或者在以后的代码中会调用到起点的状态,而因为没有处理好初始的状态导致自己后面的结果出现错误..
  2. 无论做什么题,一定要将思路完全透彻之后再去码题..
    要不然可能自己带着错误的思路打了半天代码..就算看 TJ 也看不出自己的错误所在..
    甚至还可能自己调了半天,哪怕是注意到了自己代码的某个地方,却也看不出 ta 是错误的..
  3. 初始化要定义好位置啊..不要急急忙忙最后吃不到热豆腐..
D_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define re register ll
#define mp make_pair
#define lf double
#define le strlen
const ll mod=1e9+7;
inline void read(ll &ss)
{
	ss=0;
	ll cit=0;
	char ch;
	ch=getchar();
	while((ch>'9') or (ch<'0'))
	{
		if(ch=='-') cit=1;
		ch=getchar();
	}
	while((ch<='9') and (ch>='0'))
	{
		ss=(ss<<3)+(ss<<1)+(ch^48);
		ch=getchar();
	}
	if(cit) ss=-ss;
}
ll n,m,mc,ts;
ll a[20000];
ll w[20000];
ll c[20000];
map<ll,bool> force;
ll crit;
ll maxn;
ll rounds;
ll minn=1e9;
ll posi;
ll HP;
map<ll,bool> uniq;
ll dp[2000][2000];//单向攻击..
struct Fighting
{
	ll step;
	ll grade;
	ll power;
}z[1000000],z2[1000000];
ll cnt;
map<pair<ll,ll>,bool> maplive;
inline void dfs()
{
	deque<Fighting> que;
	Fighting now;
	que.push_back((Fighting){1,0,1});
	maplive[mp(1,1)]=1;
	while(!que.empty())
	{
		now=que.front();
		que.pop_front();
		if(now.step>=rounds) break;
		que.push_back((Fighting){now.step+1,now.grade+1,now.power});
		maplive[mp(now.step+1,now.power)]=1;
		if(now.grade>1 and now.grade*now.power<=HP and maplive[mp(now.step+1,now.power*now.grade)]==0)
		{
			maplive[mp(now.step+1,now.power*now.grade)]=1;
			que.push_back((Fighting){now.step+1,now.grade,now.grade*now.power});
			z[++cnt].step=now.step+1;
			z[cnt].power=now.grade*now.power;
		}
	}
	return ;
}
inline bool cmp(Fighting aa,Fighting bb)
{
	if(aa.power==bb.power) 
		return aa.step<bb.step;
	return aa.power<bb.power;
}
signed main()
{
	read(n);
	read(m);
	read(mc);
	for(re i=1;i<=n;++i) read(a[i]);
	for(re i=1;i<=n;++i) read(w[i]);
	for(re i=1;i<=m;++i)
	{
		 read(c[i]);
		 HP=max(HP,c[i]);
	}
	for(re i=1;i<=n;++i)
	{
		for(re j=mc;j>=a[i];--j)
		{	
			dp[i][j-a[i]]=max(dp[i][j-a[i]],dp[i-1][j]+1);
			dp[i][min(mc,j-a[i]+w[i])]=max(dp[i][min(mc,j-a[i]+w[i])],dp[i-1][j]);
		}
	}
	for(re i=1;i<=n;i++)
	{
		for(re j=1;j<=mc;j++)
		{
			rounds=max(dp[i][j],rounds);
		}
	}
	dfs();
	ll tot=0;
	sort(z+1,z+cnt+1,cmp);
	for(re i=1;i<=cnt;++i)
	{
		if(force[z[i].power]==0)
		{
			z2[++tot]=z[i];
		}
	}
	#define z z2
	#define cnt tot
	for(re i=1;i<=m;i++)
	{
		crit=0;
		if(c[i]<=rounds)
		{
			putchar('1');
			putchar('\n');
			continue;
		}
		minn=(ll)INT_MAX;
		for(re j=cnt,k=1;j>=1;--j)
		{
			while(k<cnt and z[k].power+z[j].power<=c[i])
			{
				if(minn>z[k].step-z[k].power)
				{
					minn=z[k].step-z[k].power;
					posi=k;
				}
				k++;
			}
			if(z[j].power<=c[i] and z[j].power+rounds-z[j].step>=c[i]) 
			{
				crit=1;
				break;
			}
			if(z[j].power+z[posi].power<=c[i] and z[j].power+rounds-z[j].step-minn>=c[i])
			{
				crit=1;
				break;
			}
		}
		if(crit==0) 
		{
			putchar('0');
			putchar('\n');
		}
		else
		{	
			putchar('1');
			putchar('\n');
		}
	}
	return 0;
}
posted @ 2021-06-06 20:53  AaMuXiiiiii  阅读(64)  评论(0编辑  收藏  举报