zoukankan      html  css  js  c++  java
  • 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 树上的数

    暂时弃疗。。。

  • 相关阅读:
    hdu 2732 Leapin' Lizards 最大流 拆点 建图
    Atcoder CODE FESTIVAL 2017 qual C D
    Codeforces Round #442 Div.2 A B C D E
    hdu 3549 Flow Problem 最大流 Dinic
    2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest I. Photo Processing
    Atcoder CODE FESTIVAL 2017 qual C C
    2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest A E F G H I K M
    hdu 5952 Counting Cliques 求图中指定大小的团的个数 暴搜
    TensorFlow深度学习,一篇文章就够了
    Vim常用的基本操作
  • 原文地址:https://www.cnblogs.com/tangzhiyang/p/11964242.html
Copyright © 2011-2022 走看看