zoukankan      html  css  js  c++  java
  • 10.2 正睿国庆集训测试1


    2018.10.2 Test

    时间:3.5h
    期望得分:100+50+20
    实际得分:40+45+20

    比赛链接

    总结

    感觉自己是个zz

    A 陈太阳与取模

    题目链接

    [egin{aligned}c\%x&equiv (c\%A)\%x\c\%x&equiv (c-lfloorfrac ca floor*a)\%x\c\%x&equiv c\%x-lfloorfrac ca floor*a\%x\(lfloorfrac ca floor*a)\%x&equiv 0end{aligned} ]

    (x)应是(lfloorfrac ca floor*a)的约数。
    (cin[l,r]),如果(frac la=frac ra)那么(x)可以是(lfloorfrac ca floor imes a)的约数;
    否则至少存在(lfloorfrac la floor imes a)((lfloorfrac la floor+1) imes a)(x)只能是(a)的约数。
    然后求约数个数就好了。。

    //58ms	496kb
    #include <cmath>
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    typedef long long LL;
    
    inline LL read()
    {
    	LL now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    void Div(LL x)
    {
    	LL ans=1;
    //	for(int i=2,lim=sqrt(x); i<=lim; ++i)
    	for(int i=2; 1ll*i*i<=x; ++i)
    		if(!(x%i))
    		{
    			int cnt=1;
    			while(!(x%i)) x/=i, ++cnt;
    			ans*=cnt;
    		}
    	if(x!=1) ans<<=1ll;
    	printf("%lld
    ",ans);
    }
    void Work()
    {
    	LL L=read(),R=read(),A=read();
    	if(A>R) return (void)puts("-1");
    	L/A==R/A ? Div(L/A*A) : Div(A);
    }
    
    int main()
    {
    //	freopen("ex_modulo3.in","r",stdin);
    	for(int T=read(); T--; Work());
    	return 0;
    }
    

    B 陈太阳与路径(树形DP)

    题目链接

    因为随机树的高度是有保证的,Prufer序列生成的随机树最大深度的期望为(O(sqrt n)),平均深度为(O(log n))
    所以我们可以用两次复杂度为(O(n*dep))的树形DP求出每个点的答案。这样空间复杂度也是(O(n*dep))的。
    DP数组的有用大小只与深度有关,可以用vector或者指针动态分配内存。另外以直径的中点为根深度就可以/2。
    这样最终复杂度大概就是(O(nlog n))

    另外可以用长链剖分做,对于每一条长链维护一个DP数组,第二遍DFS时只需要将非长链合并到长链上。
    这样任何树都能做,复杂度(O(n))
    这样任何树向下部分的DP都能做,复杂度(O(n))。但是向上部分的DP是个卷积,还是没办法。
    ——by dls

    //1355ms	94896kb
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 200000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=5e5+5;
    
    int Enum,H[N],nxt[N<<1],to[N<<1],fa[N],pre[N],dis[N],dep[N];
    int pool[30000000],*Now=pool,*F[N],*G[N];
    LL ans[N];
    char IN[MAXIN],*SS=IN,*TT=IN,OUT[6000000],*O=OUT;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    void print(LL x)
    {
    	if(x>9) print(x/10);
    	*O++ = x%10+'0';
    }
    inline void AE(int u,int v)
    {
    	to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    	to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
    }
    int BFS(int s)
    {
    	static int q[N];
    	int h=0,t=1;
    	q[0]=s, dis[s]=pre[s]=0;
    	while(h<t)
    	{
    		int x=q[h++];
    		for(int i=H[x],v; i; i=nxt[i])
    			if((v=to[i])!=pre[x])
    				dis[v]=dis[x]+1, pre[v]=x, q[t++]=v;
    	}
    	return q[t];
    }
    void DFS0(int x)
    {
    	int tmp=0;
    	for(int i=H[x],v; i; i=nxt[i])
    		if((v=to[i])!=fa[x])
    			fa[v]=x, DFS0(v), tmp=std::max(tmp,dep[v]+1);
    	dep[x]=tmp;
    	F[x]=Now, Now+=tmp+1, G[x]=Now, Now+=tmp+1;
    }
    void DFS1(int x)
    {
    	int *f=F[x]; LL res=0;
    	for(int i=H[x],v; i; i=nxt[i])
    		if((v=to[i])!=fa[x])
    		{
    			DFS1(v); int *fv=F[v];
    			for(int j=0; j<=dep[v]; ++j)
    				res+=1ll*f[j]*fv[j], f[j]+=fv[j];
    		}
    	for(int i=dep[x]; i; --i) f[i]=f[i-1];
    	f[0]=1, ans[x]=res;
    }
    void DFS2(int x)
    {
    	int *g=G[x],*gf=G[fa[x]],*f=F[x],*ff=F[fa[x]];
    	if(x!=1)
    	{
    		for(int i=1; i<=dep[x]; ++i)
    		{
    			g[i]=gf[i-1]+ff[i-1];
    			if(i>=2) g[i]-=f[i-2];
    			ans[x]+=1ll*g[i]*f[i];
    		}
    	}
    	for(int i=H[x],v; i; i=nxt[i])
    		if((v=to[i])!=fa[x]) DFS2(v);
    }
    
    int main()
    {
    //	freopen("ex_diameter3.in","r",stdin);
    //	freopen("my.out","w",stdout);
    
    	int n=read();
    	for(int i=1; i<n; ++i) AE(read(),read());
    
    	int s=BFS(1), rt=BFS(s), d=dis[rt]>>1;
    	while(dis[rt]>d) rt=pre[rt];
    	DFS0(rt), DFS1(rt), DFS2(rt);
    
    	for(int i=1; i<n; ++i) print(ans[i]+1), *O++=' '; print(ans[n]+1);
    	fwrite(OUT,O-OUT,1,stdout);
    
    	return 0;
    }
    

    C 陈太阳与开关

    题目链接

    我们将开关改变的点设成黑色,不变的点设成白色,将连接不同颜色的点的边的存在性反转(连接同色点的边存在性自然不变)。
    这样原题中的每个方案对应一个黑白染色的方案(废话)。
    因为连出的边是(O(n^2))级别的,原图只存在(O(n))条边,所以不连通的情况非常少,我们考虑算不连通(不合法)的方案数(强行解释?不管了)

    假设按下开关的点为黑点,考虑什么时候某个点为黑点时图不连通。令它在原图上的邻接点为白点,这圈白点之外的全为黑点,那这个点不与任何点有边,即被孤立了。称这个点为孤立点。

    题解:考虑两个相邻的同色点,设它们为黑点,那么任何一个白点至少与这两个点之一连通(如果都不连通说明在原图都连通,那就是个环了),即整个白色点集与这两个黑点连通(即白色点不可能成为孤立点)。
    那么如果存在黑色点(x)不与这两个黑点连通,则(x)不与任何白点有连边,那么在原树中(x)与所有白点相邻。这样它是一个孤立点。
    那么一个点是孤立点当且仅当其相邻点集为整个异色点集。
    一个方案合法当且仅当不存在孤立点。

    我们发现所有点都可以成为孤立点并使得图不连通,且某个染色方案最多存在一个孤立点(否则两个孤立点都与所有异色点相连,就又不是树了)。
    那么我们枚举每个点作为孤立点就可以得到(O(n))种不合法的染色方案。
    因为把所有点颜色取反,所有边的存在性不会改变,所以一个孤立点对应两种不合法的染色

    但是某两个点做孤立点时它们的染色方案可能是相同的。
    然后我们发现重复的染色情况只可能是叶节点做孤立点。我们把叶节点的情况放到它的邻接点上判就行了(算某个叶子(x)时,如果(fa[x])标记过,不算再答案;否则标记(fa[x])算它的答案)。

    我们发现还有一种不合法的染色方案,即对一条链交替染色。
    当链上有(2,3,4,5)个点时,方案不合法,但都对应某个点是孤立点的情况。
    当链上多于(6)个点时,它合法。
    当链上有(6)个点时,它仍不合法,但这不对应某个点是孤立点的情况。而且如果是(4)个点的链,链两端各连至少一个叶子(只能是叶子),那么这都是没有被判的不合法情况。
    那我们枚举一下边,直接判有没有(4)个点的链且满足它就行了。这样不合法方案数为((4+2+1)*2=14)种。

    上面是神仙rqy的做法。
    题解:

    再判下特殊情况就完了。
    至于为什么只有每个点为孤立点和交替染色这两种方案,或者交替染色只有两种多余不合法方案,不知道。等老师回(或者就靠猜啊)

    yjz:你画两分钟图就知道,只有这两种情况了。
    ...

    
    

    考试代码

    B

    为什么就是跑得比zzx慢。。(虽然一个分吧)

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 200000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=5e5+5;
    
    int Enum,H[N],nxt[N<<1],to[N<<1],dgr[N],f[N],numx[N],num[N],Maxd;
    LL ans[N];
    char IN[MAXIN],*SS=IN,*TT=IN,OUT[6000000],*O=OUT;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    void print(LL x)
    {
    	if(x>9) print(x/10);
    	*O++ = x%10+'0';
    }
    inline void AE(int u,int v)
    {
    	++dgr[v], to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    	++dgr[u], to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
    }
    void DFS0(int x,int fa)
    {
    	int tmp=0;
    	for(int i=H[x],v; i; i=nxt[i])
    		if((v=to[i])!=fa)
    			DFS0(v,x), tmp=std::max(tmp,f[v]);
    	f[x]=tmp+1;
    }
    //void DFS1(int x,int fa)
    //{
    //	if(dgr[x]==1) {fi[x]=0, se[x]=N; return;}
    //	int f=N,s=N;
    //	for(int i=H[x],v; i; i=nxt[i])
    //		if((v=to[i])!=fa)
    //		{
    //			DFS1(v,x);
    //			if(fi[v]<f) s=f, f=fi[v], pos[x]=v;
    //			else s=std::min(s,fi[v]);
    //		}
    //	::f[x]=fi[x]=f+1, se[x]=s+1;
    //}
    //void DFS2(int x,int fa)
    //{
    //	for(int i=H[x],v; i; i=nxt[i])
    //		if((v=to[i])!=fa)
    //		{
    //			if(pos[x]==v) f[v]=std::min(se[x]+1,f[v]);
    //			else f[v]=std::min(fi[x]+1,f[v]);
    //			DFS2(v,x);
    //		}
    //}
    void DFS3(int x,int fa,int d,int dep)
    {
    	Maxd=std::max(Maxd,d);
    	++num[d], ++d;
    	if(!--dep) return;
    	for(int i=H[x]; i; i=nxt[i])
    		if(to[i]!=fa) DFS3(to[i],x,d,dep);
    }
    
    int main()
    {
    	freopen("ex_diameter2.in","r",stdin);
    	freopen("my.out","w",stdout);
    
    	int n=read();
    	for(int i=1; i<n; ++i) AE(read(),read());
    
    	DFS0(1,1);
    //	DFS1(1,1), DFS2(1,1);
    //	for(int i=1; i<=n; ++i) printf("f[%d]=%d fi[%d]=%d se[%d]=%d
    ",i,f[i],i,fi[i],i,se[i]);
    	for(int x=1; x<=n; ++x)
    		if(dgr[x]==1) ans[x]=1;
    		else
    		{
    			LL res=1; int tmp=f[x]-1; Maxd=1;
    			for(int i=H[x]; i; i=nxt[i])
    			{
    				DFS3(to[i],x,1,tmp);
    				for(int j=1; j<=Maxd&&num[j]; ++j)
    					res+=1ll*numx[j]*num[j], numx[j]+=num[j], num[j]=0;
    			}
    			for(int i=1; i<=tmp; ++i) numx[i]=0;
    			ans[x]=res;
    		}
    	for(int i=1; i<n; ++i) print(ans[i]), *O++=' '; print(ans[n]);
    	fwrite(OUT,O-OUT,1,stdout);
    
    	return 0;
    }
    

    C

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define gc() getchar()
    #define mod 1000000007
    typedef long long LL;
    const int N=1e5+5;
    
    int n,Enum,H[N],nxt[N<<1],to[N<<1];
    bool mp[21][21],rev0[21],vis0[21];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline void AE(int u,int v)
    {
    	to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    	to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
    }
    int DFS0(int x)
    {
    	int res=1; vis0[x]=1;
    	for(int i=1; i<=n; ++i)
    		if(!vis0[i] && (rev0[x]^rev0[i]^mp[x][i])) res+=DFS0(i);
    	return res;
    }
    bool Check()
    {
    	memset(vis0,0,sizeof vis0);
    	return DFS0(1)==n;
    }
    void Subtask1()
    {
    	memset(mp,0,sizeof mp);
    	for(int x=1; x<=n; ++x)
    		for(int i=H[x]; i; i=nxt[i]) mp[x][to[i]]=1;
    
    	int ans=1,all=(1<<n)-1;
    	for(int s=1; s<=all; ++s)
    	{
    		for(int i=0; i<n; ++i) if(s>>i&1) rev0[i+1]=1;
    		ans+=Check();
    		for(int i=0; i<n; ++i) if(s>>i&1) rev0[i+1]=0;
    	}
    	printf("%d
    ",ans);
    }
    void Work()
    {
    	Enum=0, memset(H,0,sizeof H);
    
    	n=read();
    	for(int i=1; i<n; ++i) AE(read(),read());
    	if(n<=20) {Subtask1(); return;}
    	
    	
    }
    
    int main()
    {
    //	freopen("ex_trigger1.in","r",stdin);
    //	freopen(".out","w",stdout);
    
    	for(int T=read(); T--; Work());
    	return 0;
    }
    
  • 相关阅读:
    Linux
    Linux
    Linux
    Linux
    Linux
    Python
    Linux
    Python
    MySQL
    Python
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9737888.html
Copyright © 2011-2022 走看看