CSP2019-S2总结

前言

赛时:好难啊,什么都不会
刚结束:原来如此
现在:为什么我这么菜


洛谷 5657 格雷码

代码(找规律)

#include <cstdio>
using namespace std;
typedef unsigned long long ull;
ull k,now=1; char c[101]; int n;
int main(){
	scanf("%d%llu",&n,&k);
	for (int i=1;i<=n;++i){
		if (((k/now)&3)==1||((k/now)&3)==2) c[n-i+1]=49;
		    else c[n-i+1]=48;
		now<<=1;
	}
	for (int i=1;i<=n;++i) putchar(c[i]);
	return 0;
}

洛谷 5658 括号树

题目


分析

考虑在树上动态维护一个装入左括号的栈,
一个显然的性质就是以(i)结尾的合法括号串个数等于前一个左括号的前驱的个数+1
但是赛时只想到这个性质没有想到用栈维护QWQ


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=500011; long long ans,s[N];
struct node{int y,next;}e[N];
int col[N],top,st[N],cnt[N],ls[N],n,k=1,fat[N];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void dfs(int x){
	rr int tmp=0;
	if (col[x]){
		if (top){
			tmp=st[top];
			cnt[x]=cnt[fat[tmp]]+1;
			--top;
		}
	}else st[++top]=x;
	s[x]=s[fat[x]]+cnt[x];
	for (rr int i=ls[x];i;i=e[i].next)
	    dfs(e[i].y);
	if (tmp) st[++top]=tmp;
	    else if (top) --top; 
}
signed main(){
	n=iut();
	for (rr int i=1;i<=n;++i){
		rr char c=getchar();
		while (c!='('&&c!=')') c=getchar();
		col[i]=c==')';
	}
	for (rr int i=2;i<=n;++i){
		rr int x=iut(); fat[i]=x;
		e[++k]=(node){i,ls[x]},ls[x]=i;
	}
	dfs(1);
	for (rr int i=1;i<=n;++i) ans^=1ll*s[i]*i;
	return !printf("%lld",ans);
} 

洛谷 5659 树上的数

待更


洛谷 5664 Emiya 家今天的饭

待更


洛谷 5665 划分

题目


分析

单调队列裸题,考场没想到qwq
不过这题比较恶心的是要用高精度
根据((a+b)^2>a^2+b^2)可以知道要尽量多分段
(dp[i])表示前(i)个位置所能取到的最大的(j)
那么(dp[i]=max{j}[s_i-s_jgeq s_j-s_{dp[j]}])
由于(s)是单调递增的,那么可以用单调队列维护


代码

#include <cstdio>
#include <cctype>
#define rr register
#define calc(x) ((s[x]<<1)-s[dp[x]])
using namespace std;
const int aod=1073741823,N=40000011;
typedef unsigned uit;
typedef long double ld;
typedef long long lll; lll s[N];
int n,typ,q[N],dp[N],head,tail;
const lll mod=100000000000000000ll;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline lll mul(lll a,lll b){
    a%=mod,b%=mod;
    rr lll c=(ld)a*b/mod,ans=a*b-c*mod;
    ans=ans<0?ans+mod:(ans>=mod?ans-mod:ans);
    return ans;
}
signed main(){
	n=iut(),typ=iut();
	if (!typ){
		for (rr int i=1;i<=n;++i) s[i]=s[i-1]+iut();
	}else {
		rr uit X=iut(),Y=iut(),Z=iut(),a1=iut(),a2=iut(),a3;
		iut(),s[1]=a1,s[2]=a2; rr int TAIL=iut(),L=iut(),R=iut();
		for (rr int i=1;i<3;++i){
			a3=s[i]%(R-L+1)+L,s[i]=s[i-1]+a3;
			if (TAIL==i&&TAIL<n) TAIL=iut(),L=iut(),R=iut();
		}
		for (rr int i=3;i<=n;++i){
			a3=(a2*X+a1*Y+Z)&aod,a1=a2,a2=a3;
			a3=a3%(R-L+1)+L,s[i]=s[i-1]+a3;
			if (TAIL==i&&TAIL<n) TAIL=iut(),L=iut(),R=iut();
		}
	}
	for (rr int i=1;i<=n;++i){
		while (head<tail&&s[i]>=calc(q[head+1])) ++head;
		dp[i]=q[head];
		while (head<tail&&calc(q[tail])>=calc(i)) --tail;
		q[++tail]=i;
	}
	rr lll ans[2]={0,0},t[2];
	for (rr int i=n;i;i=dp[i]){
		rr lll t1=s[i]-s[dp[i]];
		t[1]=mul(t1,t1),t[0]=(ld)t1*t1/mod;
		ans[0]+=t[0],ans[1]+=t[1];
		if (ans[1]>=mod) ++ans[0],ans[1]-=mod;
	}
	if (ans[0]) printf("%lld%017lld",ans[0],ans[1]);
	    else printf("%lld",ans[1]);
	return 0;
}

洛谷 5666 树的重心

待更


后记

wtcl,什么都不会

原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13823388.html