NOIP2018游记

NOIP2018游记

凉夜竹堂虚,小睡匆匆醒。银漏无声月上阶,满地阑干影。何处最知秋,风在梧桐井。不惜骖鸾弄玉箫,露湿衣裳冷。

首先考试的时候心态有问题,考试前的目标大概是NOIP450+

最后却389分滚粗

D-inf

平时的学习不太认真,天赋也不是很好,NOIP信心不足啊。

D-1

考了一次NOIP信心赛,然后我就被卡常了,难道是NOIP爆炸的前兆。

D0

考试前一天机房颓废,然后和我一起颓废的小伙伴都考炸了,果然NOIP前不能颓废,不然就等死吧

考试前毒奶的数论,Tarjan都没考,难道NOIP不考Tarjan?

D1

T1 T2 200后,T3就没有太仔细去思考,直接敲了一发暴力就走人,考试结束后才发现自己的暴力和正解相差无几(方法一样),最后D1 255分滚粗走人,考完听大佬说T1原题?周围一群人T1AK,心态就炸了。

D2

T1,敲了1h都没有敲出来心态有点爆炸,最后在 1h30min时敲了出来,过了环的样例,最后却没有测试树的样例导致T1 40分,T2 推导了一波状压感觉有些困难果断看T3,发现T3可能是个倍增,然后开始敲,但是最后想崩了,敲了个暴力(44分)走人,开始看T2,感觉可做,但是有一种特殊情况没有考虑到,推到考试结束,最后只有50分。

两天下来 \(255+134=389\) 太低了,冬令营是没有希望了,只能好好准备省选了。

其实通过这次考试,我总结出了以下经验

① 考试不要紧张

② 要尽量写自己会做的所有分

③ 将以后的每场考试都当做正式考试对待

感觉快要退役了,先把BZOJ的题做一做,先把计算几何,各种数据结构,动态点分治,倍增,网络流,数论都学一学,冲刺以下明年的省选吧。

D1T1代码祭天

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
const int inf=1<<30;
int val[maxn];
int n;
inline int read()
{
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+(ch^'0'),ch=getchar();
	return x;
}
int sum[maxn<<2],pos[maxn<<2];
int lazy[maxn<<2];
bool flag[maxn<<2];
inline void pushup(int rt)
{
    if(sum[rt<<1]>sum[rt<<1|1])pos[rt]=pos[rt<<1|1],sum[rt]=sum[rt<<1|1];
    else pos[rt]=pos[rt<<1],sum[rt]=sum[rt<<1];
    flag[rt]=flag[rt<<1]|flag[rt<<1|1];
}
inline void build(int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]=val[l];
        pos[rt]=l;
        return ;
    }
    int mid=l+r>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}
inline void pushdown(int rt)
{
    if(lazy[rt])
    {
        sum[rt<<1]+=lazy[rt];
        sum[rt<<1|1]+=lazy[rt];
        lazy[rt<<1]+=lazy[rt];
        lazy[rt<<1|1]+=lazy[rt];
        lazy[rt]=0;
    }
}
void update(int L,int R,int l,int r,int rt,int v)
{
    if(L<=l&&r<=R)
    {
        lazy[rt]+=v;
        sum[rt]+=v;
        return ;
    }
    int mid=l+r>>1;
    pushdown(rt);
    if(L<=mid)update(L,R,l,mid,rt<<1,v);
    if(R>mid)update(L,R,mid+1,r,rt<<1|1,v);
    pushup(rt);
}
void change(int poss,int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]=inf;
        flag[rt]=1;
        return ;
    }
    int mid=l+r>>1;
    pushdown(rt);
    if(poss<=mid)change(poss,l,mid,rt<<1);
    else change(poss,mid+1,r,rt<<1|1);
    pushup(rt);
}
int check(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)return flag[rt];
    int mid=l+r>>1;
    pushdown(rt);
    int ans=0;
    if(L<=mid)ans|=check(L,R,l,mid,rt<<1);
    if(R>mid)ans|=check(L,R,mid+1,r,rt<<1|1);
    return ans;
}
inline int queryl(int pos)
{
	int l=1,r=pos,ans=pos;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid,pos,1,n,1)!=1)ans=mid,r=mid-1;
		else l=mid+1;
	}
	return ans;
}
inline int queryr(int pos)
{
	int l=pos,r=n,ans=pos;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(pos,mid,1,n,1)!=1)ans=mid,l=mid+1;
		else r=mid-1;
	}
	return ans;
}
int main()
{
	freopen("road.in","r",stdin);
	freopen("road.out","w",stdout);
	n=read();
	for(int i=1;i<=n;i++)val[i]=read();
	long long ans=0;
	int cnt=0;
	build(1,n,1);
	while(cnt<n)
	{
		int poss=pos[1],num=sum[1];
		while(num==0)
		{
			cnt++;
			change(poss,1,n,1);
			poss=pos[1],num=sum[1];
		}
		if(cnt==n)break;
		int l=queryl(poss),r=queryr(poss);
		update(l,r,1,n,1,-num);
		ans+=num;
	}
	printf("%lld\n",ans);
	return 0;
}

posted @ 2018-11-17 09:31  Harry_bh  阅读(235)  评论(0编辑  收藏  举报