• 测试「20201028测试总结」


    教练终于考NOIP模拟题了。


    T1

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

    ( ext{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
    ",(int)ans);
    	return 0;
    }
    

    T2

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

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

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

    ( ext{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
    1"),0;
    	if(n==2) return puts("1
    1 1"),0;
    	if(n==3) return puts("2
    1 1 2"),0;
    	if(n==4) return puts("2
    1 1 2 2"),0;
    	if(n==5) return puts("3
    2 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。

    ( ext{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
    ",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
    ",ans);
    	}
    	return 0;
    }
    

    T4

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

    [dis(l,x)=x ]

    的个数。

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

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

    树上差分即可求出答案。

    ( ext{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
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    java实现土地测量
    java实现土地测量
    java实现土地测量
    java实现土地测量
    ajax异步获取数据后动态向表格中添加数据(行)
    jquery如何通过ajax请求获取后台数据显示在表格上
    Eclipse4.5在线安装Aptana插件及配置代码提示教程
    eclipse安装Aptana 插件,并设置使之能提示css,js,html,帮助编写代码
    jsp页面根据json数据动态生成table
    Jquery根据JSON生成Table
  • 原文地址:https://www.cnblogs.com/syc233/p/13889868.html
Copyright © 2020-2023  润新知