Loading

测试「20201028测试总结」

教练终于考NOIP模拟题了。


T1

真 · 签到题,直接使用math库函数即可。

\(\text{Code}:\)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long lxl;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline void read(T &x)
{
	x=0;T f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	x*=f;
}

int n,m;

int main()
{
#ifndef ONLINE_JUDGE
	freopen("check.in","r",stdin);
	freopen("check.out","w",stdout);
#endif
	read(n),read(m);
	long double ans=exp(log((long double)n)/(long double)m);
	printf("%d\n",(int)ans);
	return 0;
}

T2

先只考虑除了 \(2\) 以外的质数,发现只有偶数和奇数之间连边,也就是一个二分图,可以只用两种颜色。

考虑 \(2\) 其实是将偶数和奇数分别连成一条链,我们让链上的颜色交替出现即可。

发现这样最多只有 \(4\) 种颜色,\(n\) 比较小的时候打表即可。

\(\text{Code}:\)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long lxl;
const int maxn=1e4+5;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline void read(T &x)
{
	x=0;T f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	x*=f;
}

int n,color[maxn];

int main()
{
#ifndef ONLINE_JUDGE
	freopen("color.in","r",stdin);
	freopen("color.out","w",stdout);
#endif
	read(n);
	if(n==1) return puts("1\n1"),0;
	if(n==2) return puts("1\n1 1"),0;
	if(n==3) return puts("2\n1 1 2"),0;
	if(n==4) return puts("2\n1 1 2 2"),0;
	if(n==5) return puts("3\n2 1 1 3 2"),0;
	for(int i=1,type=0;i<=n;i+=2,type^=1)
		color[i]=1+type;
	for(int i=2,type=0;i<=n;i+=2,type^=1)
		color[i]=3+type;
	puts("4");
	for(int i=1;i<=n;++i)
		printf("%d ",color[i]);
	return 0;
}

T3

没怎么看懂,想找出题人对线,但是找不到出题人/kk。

\(\text{Code}:\)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long lxl;
const int maxn=2e5+5;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline void read(T &x)
{
	x=0;T f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	x*=f;
}

lxl n,m,k,a[maxn];
lxl D;

int main()
{
#ifndef ONLINE_JUDGE
	freopen("array.in","r",stdin);
	freopen("array.out","w",stdout);
#endif
	int T;read(T);
	while(T--)
	{
		read(n),read(m),read(k),read(D);
		lxl sum=0;
		for(int i=1;i<=m;++i) read(a[i]),sum+=a[i];
		sort(a+1,a+m+1);
		lxl ans=0;
		for(int i=1;i<=m;++i)
		{
			lxl Min=min(n,D/sum);
			ans=max(ans,n*(i-1)+Min*(m-i+1)+min(n-Min,(D-sum*Min)/a[i])+Min*k);
			if(D<a[i]*n)
			{
				ans=max(ans,D/a[i]+n*(i-1));
				break;
			}
			if(i!=m)
			{
				lxl tmp=(D-a[i]*n)/(sum-a[i])+1;
				if(D>=tmp*sum)
					printf("%lld %lld\n",tmp+min(n-tmp,(D-tmp*sum)/a[i]),tmp),
					ans=max(ans,n*(i-1)+tmp*(m-i+1)+min(n-tmp,(D-tmp*sum)/a[i])+tmp*k);
			}
			sum-=a[i];
			D-=a[i]*n;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

T4

其实就是求树上路径上点 \(x\) 满足:

\[dis(l,x)=x \]

的个数。

分成 \(l\to LCA\)\(LCA\to r\) 两部分考虑。将式子拆开,得到:

\[\begin{aligned} dep_l-dep_x=x&\implies dep_l=x+dep_x\\ dep_l+dep_x-2\times dep_{LCA}=x&\implies dep_l-2\times dep_{LCA}=x-dep_x \end{aligned} \]

树上差分即可求出答案。

\(\text{Code}:\)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long lxl;
const int maxn=3e5+5;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline void read(T &x)
{
	x=0;T f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	x*=f;
}

struct edge
{
	int u,v,next;
	edge(int u,int v,int next):u(u),v(v),next(next){}
	edge(){}
}e[maxn<<1];

int head[maxn],ecnt;

inline void add(int u,int v)
{
	e[ecnt]=edge(u,v,head[u]);
	head[u]=ecnt++;
}

int n,m;

namespace Tree
{
	int dep[maxn],fa[maxn],son[maxn],siz[maxn],top[maxn];
	void dfs1(int u)
	{
		dep[u]=dep[fa[u]]+1;
		siz[u]=1;
		for(int i=head[u];~i;i=e[i].next)
		{
			int v=e[i].v;
			if(v==fa[u]) continue;
			fa[v]=u;
			dfs1(v);
			siz[u]+=siz[v];
			if(siz[v]>siz[son[u]]) son[u]=v;
		}
	}
	void dfs2(int u,int t)
	{
		top[u]=t;
		if(!son[u]) return;
		dfs2(son[u],t);
		for(int i=head[u];~i;i=e[i].next)
		{
			int v=e[i].v;
			if(v==fa[u]||v==son[u]) continue;
			dfs2(v,v);
		}
	}
	inline int LCA(int a,int b)
	{
		for(;top[a]!=top[b];dep[top[a]]>dep[top[b]]?a=fa[top[a]]:b=fa[top[b]]);
		return dep[a]<dep[b]?a:b;
	}
}

struct ques // 询问从根到这个点的路径上有多少点 dep_i+i==val 或者 i-dep_i==val
{
	int val,id,type;
	ques(int val,int id,int type):val(val),id(id),type(type){}
	ques(){}
};

pair<int,int> querys[maxn];
vector<ques> Q[maxn];
vector<ques>::iterator it;
int ans[maxn];

int val[maxn];
int sum[maxn<<1];

void dfs(int u)
{
	++sum[val[u]];
	for(it=Q[u].begin();it!=Q[u].end();++it)
		ans[it->id]+=it->type*sum[it->val];
	Q[u].clear();
	for(int i=head[u];~i;i=e[i].next)
	{
		int v=e[i].v;
		if(v==Tree::fa[u]) continue;
		dfs(v);
	}
	--sum[val[u]];
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("query.in","r",stdin);
	freopen("query.out","w",stdout);
#endif
	read(n),read(m);
	memset(head,-1,sizeof(head));
	for(int i=1,u,v;i<n;++i)
	{
		read(u),read(v);
		add(u,v);add(v,u);
	}
	Tree::dfs1(1);
	Tree::dfs2(1,1);
	for(int i=1,l,r;i<=m;++i)
	{
		read(l),read(r);
		querys[i]=make_pair(l,r);
	}
	for(int i=1;i<=n;++i)
		val[i]=i+Tree::dep[i];
	for(int i=1;i<=m;++i)
	{
		int u=querys[i].first,v=querys[i].second;
		int f=Tree::LCA(u,v);
		Q[u].push_back(ques(Tree::dep[u],i,1));
		if(Tree::fa[f]) Q[Tree::fa[f]].push_back(ques(Tree::dep[u],i,-1));
	}
	dfs(1);
	for(int i=1;i<=n;++i)
		val[i]=i-Tree::dep[i]+n;
	for(int i=1;i<=m;++i)
	{
		int u=querys[i].first,v=querys[i].second;
		int f=Tree::LCA(u,v);
		Q[v].push_back(ques(Tree::dep[u]-2*Tree::dep[f]+n,i,1));
		Q[f].push_back(ques(Tree::dep[u]-2*Tree::dep[f]+n,i,-1));
	}
	dfs(1);
	for(int i=1;i<=m;++i)
		printf("%d\n",ans[i]);
	return 0;
}
posted @ 2020-10-28 11:08  GoPoux  阅读(89)  评论(0编辑  收藏  举报