zoukankan      html  css  js  c++  java
  • 9.22 正睿提高4


    2018.9.22 正睿提高5

    时间:3.5h
    期望得分:100+80+30
    实际得分:100+80+30

    比赛链接

    T2一直以为类似某道虚树题(SDOI2015)。。到最后只想写暴力(写了暴力也该想到了啊 但是已经在划水了)。

    A 数组计数(DP)

    题目链接

    DP。前缀和优化一下就行了。
    刚开始滚动数组又少清空了mmp。。

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    #define Mod(x) x>=mod&&(x-=mod)
    #define mod 998244353
    typedef long long LL;
    const int N=1e6+5;
    
    int f[2][N],sum[2][N];
    
    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;
    }
    
    int main()
    {
    	int n=read(),K=read(),now=1,las=0;
    	for(int i=1; i<=n; ++i) f[0][i]=1,sum[0][i]=i;//f[1]
    	for(int i=2; i<=K; ++i)
    	{
    		for(int j=i; j<=n; ++j)
    			f[now][j]=sum[las][j>>1];
    		sum[las][i-1]=sum[now][i-1]=0;
    		for(int j=i; j<=n; ++j)
    			sum[now][j]=sum[now][j-1]+f[now][j], Mod(sum[now][j]);
    		now=las, las^=1;
    	}
    	printf("%d
    ",f[las][n]);
    
    	return 0;
    }
    

    B 旅行(思路)

    题目链接

    如果当前到了(i),那么除了(1)(a_i)的边走一次,剩下的(1)(a_1,a_2,...,a_{i-1})的路径不与到(a_i)重叠的部分都要走两次。
    假设到(a_i)还要回到(1),那么只需要把所有走过的边计算两次。最后减去(a_i)(1)的距离即可(深度)。

    //92ms	6616kb
    #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=1e5+7;
    
    int Enum,H[N],nxt[N<<1],to[N<<1],fa[N],dep[N];
    bool vis[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    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;
    }
    void DFS(int x)
    {
    	for(int i=H[x],v; i; i=nxt[i])
    		if((v=to[i])!=fa[x]) fa[v]=x,dep[v]=dep[x]+1,DFS(v);
    }
    
    int main()
    {
    	int n=read(),q=read();
    	for(int i=1; i<n; ++i) AE(read(),read());
    	DFS(1), vis[1]=1;
    	for(int i=1,a,ans=0; i<=q; ++i)
    	{
    		a=read();
    		for(int x=a; !vis[x]; x=fa[x]) vis[x]=1,ans+=2;
    		printf("%d
    ",ans-dep[a]);
    	}
    
    	return 0;
    }
    

    C 进化(思路 二进制拆分)

    题目链接

    设a为原数组,b为进化一次后的数组,c为进化两次后的数组。
    (c_i=b_{i-1}oplus b_{i+1}=a_{i-2}oplus a_ioplus a_ioplus a_{i+2}=a_{i-2}oplus a_{i+2})
    通过打表还可以发现,a进化(2^d)次后的数组c,满足(c_i=a_{i-2^d}oplus a_{i+2^d})
    所以进化(2^d)后的数组可以(O(n))求。
    对T二进制拆分就行了。(对啊,(2^a+2^b)次后的就是(2^a)次后的再进化(2^b)次)
    还有边界的问题。我们可以构造一个环来保证这是正确的:(0 a[1sim n] 0 a[nsim 1])。这样两边的(a)是对称的,所以两个(0)始终是(0)(左边右边相等)。
    而且(a[1sim n])两边都是(0),所以最后的(a[1sim n])就是我们要求的。
    当然判左右点的时候根据这个判下下标就好了,不需要建出环来。。

    //39ms	720kb
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define pc putchar
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=1e5+5;
    
    bool A[N],B[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    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;
    }
    
    int main()
    {
    	LL T=read(); int n=read();
    	register char c=gc(); for(;!isdigit(c);c=gc());
    	bool *now=A, *las=B;
    	now[1]=c-'0';
    	for(int i=2; i<=n; ++i) now[i]=gc()-'0';
    	int len=2*n+2;
    	for(LL d=1; T; T>>=1,d<<=1)
    		if(T&1)
    		{
    			std::swap(now,las);
    			for(int i=1; i<=n; ++i)
    			{
    				int l=i-d%len, r=i+d%len;
    				if(l<0) l=-l;//关于0对称啊 
    				if(l>n) l=len-l;
    				if(r>len) r-=len;
    				if(r>n) r=len-r;
    				now[i]=las[l]^las[r];
    			}
    		}
    	for(int i=1; i<=n; ++i) pc(now[i]+'0');
    
    	return 0;
    }
    

    考试代码

    B

    #include <set>
    #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=1e5+7;
    
    int n,q,A[N],dgr[N],Enum,H[N],nxt[N<<1],to[N<<1],fa[N],dep[N],sz[N],son[N],top[N],dfn[N+3],ref[N+3];
    LL Ans;
    bool vis[N],mark[N];
    std::set<int> st;
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    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)
    {
    	++dgr[v], to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    	++dgr[u], to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
    }
    inline int LCA(int u,int v)
    {
    	while(top[u]!=top[v]) dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];
    	return dep[u]>dep[v]?v:u;
    }
    inline int Dis(int u,int v)
    {
    	if(!u||!v) return 0;
    	return dep[u]+dep[v]-(dep[LCA(u,v)]<<1);
    }
    inline bool cmp_dfn(int a,int b)
    {
    	return dfn[a]<dfn[b];
    }
    void DFS1(int x)
    {
    	int mx=0; sz[x]=1;
    	for(int i=H[x],v; i; i=nxt[i])
    		if((v=to[i])!=fa[x])
    		{
    			fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
    			if(sz[v]>mx) mx=sz[v], son[x]=v;
    		}
    }
    void DFS2(int x,int tp)
    {
    	static int Index;
    
    	top[x]=tp, ref[dfn[x]=++Index]=x;
    	if(son[x])
    	{
    		DFS2(son[x],tp);
    		for(int i=H[x]; i; i=nxt[i])
    			if(to[i]!=fa[x]&&to[i]!=son[x]) DFS2(to[i],to[i]);
    	}
    }
    bool Subtask4()
    {
    	for(int i=2; i<=n; ++i) if(dgr[i]>1) return 0;
    	int ans=0;
    	if(A[1]!=1) ++ans; printf("%d
    ",ans);
    	for(int i=2; i<=q; ++i)
    	{
    		if(A[i]==1) printf("%d
    ",ans+1);
    		else ans+=2, printf("%d
    ",ans);
    	}
    	return 1;
    }
    bool DFS3(int x,int s)
    {
    	bool fl=0;
    	for(int i=H[x],v; i; i=nxt[i])
    		if((v=to[i])!=fa[x])
    			fl|=DFS3(v,(mark[v]?1:2));
    	if(fl||vis[x]) Ans+=s;
    	return fl||vis[x];
    }
    void Subtask2()
    {
    	for(int i=1,ai; i<=q; ++i)
    	{
    		vis[ai=A[i]]=1;
    		for(int p=ai; p!=1; p=fa[p]) mark[p]=1;
    		Ans=0, DFS3(1,0), printf("%lld
    ",Ans);
    		for(int p=ai; p!=1; p=fa[p]) mark[p]=0;
    	}
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    
    	n=read(), q=read();
    	for(int i=1; i<n; ++i) AE(read(),read());
    	DFS1(1), DFS2(1,1);
    	for(int i=1; i<=q; ++i) A[i]=read();
    	if(Subtask4()) return 0;
    	if(n<=4000) return Subtask2(),0;
    //	Subtask2();
    
    	int mx=0;//Chain
    	for(int i=1,ai; i<=q; ++i)
    	{
    		ai=A[i];
    		if(dep[ai]>mx) printf("%d
    ",mx=dep[ai]);
    		else printf("%d
    ",mx+mx-dep[ai]);
    	}
    
    //	/*st.insert(0),*/ st.insert(N);
    //	LL ans=Dis(1,A[1]); printf("%lld
    ",ans);
    //	st.insert(1); if(A[1]!=1) st.insert(dfn[A[1]]);
    //
    //	std::set<int>::iterator pre,nxt;
    //	for(int i=2,ai,tmp; i<=q; ++i)//不对哎...但是还是能用来过链吧 算了 
    //	{
    //		ai=A[i];
    //		int last=ref[*(--st.rbegin())];
    //		tmp=Dis(last,ai);
    //		printf("%lld
    ",ans+tmp);
    //
    //		if(ai==1) continue;
    //
    //		pre=st.upper_bound(dfn[ai]), nxt=pre--;
    //		if(*nxt==N) ans+=Dis(ai,ref[*pre]);
    //		else ans+=Dis(ai,ref[*pre])+Dis(ai,ref[*nxt])-Dis(ref[*pre],ref[*nxt]);
    //
    //		st.insert(dfn[ai]);
    //	}
    	return 0;
    }/*
    10 6
    1 2 2 3 1 4 4 6 4 10 4 5 5 7 5 8 5 9
    10 1 7 8 3 6
    
    6 5
    1 2 2 3 3 4 5 4 6 5
    2 5 3 6 1
    
    10 9
    1 2 3 2 3 4 4 5 5 6 6 7 7 8 9 8 10 9
    7 2 3 1 9 10 4 6 5
    */
    

    C

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define pc putchar
    #define gc() getchar()
    #define MAXIN 300000
    //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=1e5+5;
    
    bool A[N],B[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    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 Output(bool *a,int n)
    {
    //	for(int i=1; i<=n; ++i) pc(a[i]+'0'),pc(' '); pc('
    ');
    	for(int i=1; i<=n; ++i)
    	{
    		if(a[i]) pc('$');
    		else pc('_');
    		pc(' ');
    	}
    	pc('
    ');
    }
    void Subtask1(int T,int n)
    {
    	for(int i=1; i<=T; ++i)
    	{
    		B[1]=A[2], B[n]=A[n-1];
    		for(int i=2; i<=n; ++i) B[i]=A[i-1]^A[i+1];
    		memcpy(A,B,sizeof A);
    //		printf("%d:	",i); Output(A,n);
    	}
    	for(int i=1; i<=n; ++i) pc(A[i]+'0');
    }
    
    int main()
    {
    //	freopen("my.out","w",stdout);
    
    	LL T=read(); int n=read();
    	register char c=gc(); for(;!isdigit(c);c=gc());
    	A[1]=c-'0';
    	for(int i=2; i<=n; ++i) A[i]=gc()-'0';
    	if(T<=1000) return Subtask1(T,n),0;
    
    	return 0;
    }/*
    100 5
    00100
    
    1000 20
    11100001110100010101
    */
    
  • 相关阅读:
    微信小程序中 数据缓存
    javascript 数组去重方法
    常用网站 ---总结
    vue面试题
    vue创建项目(命令方式)
    shutil 模块:文件复制.移动.压缩.解压.递归删除文件夹
    面向对象一些零散的知识点
    面向对象之多态
    面向对象与继承
    序列化与反序列化的三个模块:json pickle shelve
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9700848.html
Copyright © 2011-2022 走看看