• CSP2019-S 复赛游记


    Day1:

    T1 格雷码:

    题目链接

    在考场上的时候,推了十几分钟大概搞出了思路,就是倒着模拟格雷码构造的过程,一位一位推下来。但当时不知道怎么用 unsigned long long,也不知道它的范围比普通 long long 要大一点,刚好符合这道题的条件。

    于是考场上的方法如果不卡的话有95分,卡的话能被卡到80分。。。


    ull 大致用法:

    定义:unsigned long long n;
    输入输出:cout 或 printf("%llud",n);
    其他与普通 long long 一样。
    

    AC代码:

    #include<bits/stdc++.h>
    #define LL unsigned long long
    using namespace std;
    LL n,K;
    namespace P1{
    	string ans;
    	LL f2[70];
    	void solve(){
    		f2[0]=1;
    		for(LL i=1;i<=63;i++)f2[i]=f2[i-1]*2;
    		f2[64]=f2[63]-1+f2[63];
    		scanf("%llud",&K);
    		LL nw=n;
    		while(nw){
    			if(K>=f2[nw-1]){
    				ans+='1';
    				K-=f2[nw-1];
    				K=f2[nw-1]-K-1;
    			}
    			else ans+='0';
    			nw--;
    		}
    		cout<<ans;
    	}
    }
    int main(){
    	scanf("%llud",&n);
    	P1::solve();
    	return 0;
    }
    
    

    里面细节还是挺多的,特别是预处理2的幂的部分。

    T2 括号树:

    题目链接

    考场上居然只想到了 (O(n^2)) 的做法,连链的情况都没想到,也不知道是怎么了。但在luogu上能水到95分 震惊

    其实链的情况还是非常好想的,找几组样例推一下就好了,找一下规律,大概是一个前缀和的思想。

    正解在树上,和链有一些不一样,要用到类似于撤回的思想,即在栈中纪录每一次的压入弹出,回溯的时候撤回回去。

    AC代码:

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const LL N=500005;
    LL n,val[N];
    char s[N];
    vector<LL>edge[N];
    namespace P1{//n^2暴力
    	LL fa[N],dp[N],ans[N];
    	LL calc(LL x,LL v){
    		LL res=0,nw=x;
    		while(nw){
    			nw=fa[nw];
    			if(dp[nw]-dp[x]<0)break;
    			if(dp[nw]==dp[x])res++;
    		}
    		return res;
    	}
    	void dfs(LL x,LL f,LL la){
    		fa[x]=f;dp[x]=dp[f]+val[x];
    		LL nw=calc(x,dp[x]);
    		ans[x]=nw+la;
    		for(LL i=0;i<edge[x].size();i++){
    			LL y=edge[x][i];
    			if(y==f)continue;
    			dfs(y,x,la+nw);
    		}
    	}
    	void solve(){
    		dfs(1,0,0);LL res=0;
    		for(LL i=1;i<=n;i++)res^=i*ans[i];
    		printf("%lld
    ",res);
    	}
    }
    namespace P2{//链
    	LL stk[N],top,f[N],a[N];
    	void solve(){
    		for(LL i=1;i<=n;i++){
    			if(val[i]==-1&&top){
    				a[i]=a[stk[top]-1]+1;
    				top--;
    			}
    			else if(val[i]==1)stk[++top]=i;
    			f[i]=f[i-1]+a[i];
    		}
    		LL res=0;
    		for(LL i=1;i<=n;i++)res^=i*f[i];
    		printf("%lld
    ",res);
    	}
    }
    namespace P3{//正解
    	LL stk[N],top,a[N],fa[N],f[N];
    	void dfs(LL x,LL Fa){
    		fa[x]=Fa;
    		LL f1=0,f2=0;
    		if(val[x]==-1&&top){
    			f1=stk[top];
    			a[x]=a[fa[stk[top]]]+1;
    			top--;
    		}
    		else if(val[x]==1)stk[++top]=x,f2=1;
    		f[x]=f[fa[x]]+a[x];
    		for(LL i=0;i<edge[x].size();i++){
    			LL y=edge[x][i];
    			if(y==Fa)continue;
    			dfs(y,x);
    		}
    		if(f1)stk[++top]=f1;
    		else if(f2)top--;
    	}
    	void solve(){
    		dfs(1,0);
    		LL res=0;
    		for(LL i=1;i<=n;i++)res^=i*f[i];
    		printf("%lld
    ",res);
    		exit(0);
    	}
    }
    int main(){
    	scanf("%lld%s",&n,s+1);
    	for(LL i=1;i<=n;i++){
    		if(s[i]=='(')val[i]=1;
    		else val[i]=-1;
    	}bool flag=1;
    	for(LL i=2,x;i<=n;i++){
    		scanf("%lld",&x);
    		edge[x].push_back(i);
    		edge[i].push_back(x);
    		if(x!=i-1)flag=0;
    	}
    	P3::solve();
    	if(flag)P2::solve();
    	else P1::solve();
    	return 0;
    }
    
    

    T3 树上的数

    暂时弃疗。。。

  • 相关阅读:
    27个提升效率的iOS开源库推荐
    HTTP Authorization
    两种方法删除NSUserDefaults所有记录
    label调整字间距,调整行间距
    iphone手机屏幕大小
    app 图标需要的大小
    多了一层或者多层响应者 如何实现跳转
    用python实现excel中查找指定字符的行信息
    Python 遍历一个目录,输出所有的文件名
    kettle HTTP client
  • 原文地址:https://www.cnblogs.com/tangzhiyang/p/11964242.html
Copyright © 2020-2023  润新知