前言
赛时:好难啊,什么都不会
刚结束:原来如此
现在:为什么我这么菜
洛谷 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,什么都不会