zoukankan      html  css  js  c++  java
  • noip多校21

    好几天没写博客了,一直在改题,挺累的。今天的题实在有些不可改,最后剩下一些时间来写一写博客,当做总结,也当做放松一下。

    这次考试,挂分直接挂没了,问题出现在两个方面:
    1.没有计算时间复杂度,代码实现常数过大
    2.没有仔细读题,没有清楚题目让干什么。
    其实,这两个问题都是可以避免的,对于计算时空复杂度,应该是一个习惯,不能凭感觉。
    对于审题这件事,还是要细心,尤其是对于题目描述比较简单的情况下,也可以多读几遍。如果始终过不了样例也可以再读一遍题。
    剩下的就是考试策略问题,我觉得我的策略需要改进,之前都是看到那种纯数学题,期望题就直接跳过,现在觉得这样的做法是不可行的,因为最近几天的考试题都只是披着一个期望的皮,实际上和概率那些东西没什么关系,只要想一想应该就可以想出来的。
    然后就是对于考试心态,如果整套题题目都是偏难,首先要稳住心态,尽可能拿到自己可以拿到的分,以不挂分为主。

    T1 按位或

    咕了

    T2 最短路径

    思路:如果我们规定从起点出发后还要回到起点,那么我么走过的路径长度就是我经过的所有边的距离2-起点到一个点的距离。
    那么假设这(k)个点已经确定,路径长度就是经过的所有边的距离
    2-最长的链的距离。
    考虑分别计算。
    对于前一部分,我们可以在(dfs)的过程中求出。一条边有贡献当且仅当它两端都右可以当做黑点的点。那么这条边被经过的方案数就是(C_{m,k}-C_{sum,k}-C{m-sum,k}),其中,(sum)表示这条边下面的端点为根的子树中的可以作为黑点的数量。
    对于后一部分,我们枚举两个点,将这两个点之间的距离作为一条链,然后再枚举这条链可以对多少点产生贡献,用(ans-C(k-2,cnt) imes len)即可。
    代码如下:

    AC_code
    
    #include<bits/stdc++.h>
    #define int long long
    #define re register int
    #define ii inline int
    #define iv inline void
    #define next netete
    #define head haeaead
    using namespace std;
    const int N=2010;
    const int mo=998244353;
    int n,m,k,tot,ans;
    bool vis[N];
    int cun[N],jc[N],inv[N];
    int to[N<<1],next[N<<1],head[N];
    int deep[N],size[N],fa[N],top[N],son[N];
    int dis[N][N],sum[N];
    ii read()
    {
    	int x=0; char ch=getchar(); bool f=1;
    	while(ch<'0' or ch>'9')
    	{
    		if(ch=='-') f=0;
    		ch=getchar();
    	}
    	while(ch>='0' and ch<='9')
    	{
    		x=(x<<1)+(x<<3)+(ch^48);
    		ch=getchar();
    	}	
    	return f?x:(-x);
    }
    ii ksm(int d,int z)
    {
    	int out=1;
    	while(z)
    	{
    		if(z&1) out=out*d%mo;
    		z>>=1;
    		d=d*d%mo;
    	}
    	return out;
    }
    ii C(int n,int m)
    {
    	if(m>n) return 0;
    	if(m==0 or n==0) return 1;
    	return jc[n]*inv[n-m]%mo*inv[m]%mo;
    }
    iv add(int x,int y)
    {
    	to[++tot]=y;
    	next[tot]=head[x];
    	head[x]=tot;
    }
    iv dfs(int st,int f)
    {
    	fa[st]=f;
    	size[st]=1;
    	deep[st]=deep[f]+1;
    	if(vis[st]) sum[st]=1;
    	for(re i=head[st];i;i=next[i])
    	{
    		int p=to[i];
    		if(p==f) continue;
    		dfs(p,st);
    		if(sum[p] and m-sum[p]) ans=(ans+C(m,k)-C(sum[p],k)-C(m-sum[p],k)+mo+mo)%mo;
    		size[st]+=size[p];
    		sum[st]+=sum[p];
    		son[st]=(size[son[st]]>size[p])?son[st]:p;
    	}
    }
    iv dfs2(int st,int t)
    {
    	top[st]=t;
    	if(!son[st]) return ;
    	dfs2(son[st],t);
    	for(re i=head[st];i;i=next[i])
    	{
    		int p=to[i];
    		if(p==son[st] or p==fa[st]) continue;
    		dfs2(p,p);
    	}
    }
    ii get_lca(int x,int y)
    {
    	int fx=top[x],fy=top[y];
    	while(fx!=fy)
    	{
    		if(deep[fx]<deep[fy]) swap(x,y),swap(fx,fy);
    		x=fa[fx],fx=top[x];
    	}
    	return deep[x]<deep[y]?x:y;
    }
    signed main()
    {
    	freopen("tree.in","r",stdin); freopen("tree.out","w",stdout);
    	n=read(),m=read(),k=read();
    	int x,y;
    	jc[0]=1;
    	for(re i=1;i<=305;i++) jc[i]=jc[i-1]*i%mo;
    	inv[305]=ksm(jc[305],mo-2);
    	for(re i=304;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mo;
    	for(re i=1;i<=m;i++) cun[i]=read(),vis[cun[i]]=1;
    	for(re i=1;i<n;i++)
    	{
    		x=read(),y=read();
    		add(x,y),add(y,x);
    	}
    	dfs(1,0);dfs2(1,1);
    	for(re i=1;i<=m;i++)
    	{
    		for(re j=i+1;j<=m;j++)
    		{
    			int lca=get_lca(cun[i],cun[j]);
    			dis[cun[i]][cun[j]]=dis[cun[j]][cun[i]]=deep[cun[i]]+deep[cun[j]]-2*deep[lca];
    		}	
    	}
    	ans=ans*2ll%mo;
    	for(re i=1;i<=m;i++)
    	{
    		for(re j=i+1;j<=m;j++)
    		{
    			int cnt=0;
    			for(re p=1;p<=m;p++)
    			{
    				if(p==i or p==j) continue;
    				if(dis[cun[p]][cun[i]]<dis[cun[i]][cun[j]] and dis[cun[p]][cun[j]]<dis[cun[i]][cun[j]]) ++cnt;
    				else if((dis[cun[p]][cun[i]]==dis[cun[i]][cun[j]]  and p<j) and (dis[cun[p]][cun[j]]==dis[cun[i]][cun[j]] and p<i)) ++cnt;
    				else if(dis[cun[p]][cun[i]]==dis[cun[i]][cun[j]]  and p<j and dis[cun[p]][cun[j]]<dis[cun[i]][cun[j]]) ++cnt;
    				else if(dis[cun[p]][cun[j]]==dis[cun[i]][cun[j]]  and p<i and dis[cun[p]][cun[i]]<dis[cun[i]][cun[j]]) ++cnt;
    			}
    			ans=(ans-C(cnt,k-2)*dis[cun[i]][cun[j]]%mo+mo)%mo;
    		}
    	}
    	printf("%lld
    ",ans*ksm(C(m,k),mo-2)%mo);
    	return 0;	
    }
    
    

    T3 仙人掌

    咕了
    

    T4 对弈

    咕了
  • 相关阅读:
    redis 初探
    RAID,mdadm(笔记)
    EXT2文件系统
    压缩、解压缩命令(笔记)
    shell编程while
    软连接、硬链接、磁盘分区管理(笔记)
    磁盘管理(笔记)
    恢复Linux下被误删除的文件(笔记)
    Linux下高效数据恢复软件extundelete应用实战
    RedHat安装GCC问题-解决依赖问题
  • 原文地址:https://www.cnblogs.com/WindZR/p/15501040.html
Copyright © 2011-2022 走看看