新手写时的c++各种脑残错误

这一部分均于本人调试NOI05 sequence时所犯

1.scanf读变量时没加&

2.==写成=

3.!m和m搞反

4.有多个max函数嵌套的情况下还使用 #define max(x,y) ((x>y)?x:y),这样一个嵌套n次的max最后的复杂度就是O(2^n)

以下是写splay时要注意的几个地方

1.释放标记的时候要放干净

2.翻转标记叠加时应该是取反而不是清空

还有一个lyp告诉我的

用宏映射到了多个语句时要慎重,有如下情况

   #define F(x) fly(x);fly(x)

   如果我们用for (int i=1;i<=n;++i) F(i);时,实际上在循环时只会执行第一个fly(i),循环完了再执行一遍fly(n)

   如果是#define F(x) fly(x),fly(x)呢?这个实际上也是有可能出问题的,比方说下面这种情况

   在我们用问号表达式的时候(bo)?fly(x):F(x),可以发现后一个fly总是会执行的(这个例子好像有一点问题,但大概就是这个意思吧)

总之,宏定义要慎用

最后,贴一个我奋战了几个小时才搞定的sequence代码吧

#include <cstdio>

#define prep(x,y) splay(rt,x),splay(rt,y+2);

const int oo=1<<27;
const int N=5000005;
int a[N],l[N],r[N],s[N],o[N],b1[N],b2[N],c1[N],son[N],lma[N],rma[N];
int n,m,tot,rt;
int max(int x,int y) { return (x>y)?x:y; }
int U(int x) { return (x>0)?x:0; }

void up(int i)
{
	int ll=l[i],rr=r[i];
	son[i]=son[ll]+son[rr]+1;
	s[i]=s[ll]+s[rr]+a[i];
	lma[i]=max(lma[ll],s[ll]+a[i]+U(lma[rr]));
	rma[i]=max(rma[rr],s[rr]+a[i]+U(rma[ll]));
	o[i]=max(o[ll],max(o[rr],U(rma[ll])+a[i]+U(lma[rr])));
}

void left(int &i)
{
	int j=r[i];r[i]=l[j];l[j]=i;
	up(i);
	i=j;
}

void right(int &i)
{
	int j=l[i];l[i]=r[j];r[j]=i;
	up(i);
	i=j;
}

void put1(int i,int k)
{
	if (!i) return;
	b1[i]=1;b2[i]=0;c1[i]=k;
	a[i]=k;s[i]=son[i]*k;
	o[i]=lma[i]=rma[i]=(k>0)?son[i]*k:k;
}

void put2(int i)
{
	if (!i) return;
	b2[i]^=1;
	int z;
	z=lma[i],lma[i]=rma[i],rma[i]=z;
	z=l[i],l[i]=r[i],r[i]=z;
}

void lazy(int i)
{
	if (b1[i]) put1(l[i],c1[i]),put1(r[i],c1[i]),b1[i]=0;
	if (b2[i]) put2(l[i]),put2(r[i]),b2[i]=0;
}

void splay(int &i,int j)
{
	lazy(i);
	if (son[l[i]]+1>j)
		splay(l[i],j),right(i);
	else
	if (son[l[i]]+1<j)
		splay(r[i],j-son[l[i]]-1),left(i);
	if (i==rt) up(i);
}

void build(int &i,int ll,int rr)
{
	if (ll>rr) return;
	i=(ll+rr)>>1;
	build(l[i],ll,i-1);
	build(r[i],i+1,rr);
	up(i);
}

int main()
{
	freopen("sequence.in","r",stdin);
	freopen("sequence.out","w",stdout);	

	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;++i) scanf("%d",&a[i+1]);
	a[1]=a[n+2]=a[0]=o[1]=o[n+2]=o[0]=lma[0]=lma[1]=lma[n+2]=rma[0]=rma[1]=rma[n+2]=-oo;
	build(rt,1,n+2);
	tot=n+2;
	char q[10];
	for (;m;--m)
	{
		scanf("%s",q);
		if (q[2]=='S') // insert
		{
			int p,t,ll=tot;
			scanf("%d%d",&p,&t);
			for (;t;--t)
				scanf("%d",&a[++tot]);
			build(t,ll+1,tot);
			splay(rt,p+1);
			splay(r[rt],1);
			l[r[rt]]=t;
			up(r[rt]);
			up(rt);
		} else
		if (q[2]=='L') // delete
		{
			int ll,rr;
			scanf("%d%d",&ll,&rr);
			rr+=ll-1;
			prep(ll,rr);
			r[l[rt]]=0;
			up(l[rt]);
			up(rt);
		} else
		if (q[2]=='K') // make-same
		{
			int ll,rr,k;
			scanf("%d%d%d",&ll,&rr,&k);
			rr+=ll-1;
			prep(ll,rr);
			put1(r[l[rt]],k);
			up(l[rt]);
			up(rt);
		} else
		if (q[2]=='V') // reverse
		{
			int ll,rr;
			scanf("%d%d",&ll,&rr);
			rr+=ll-1;
			prep(ll,rr);
			put2(r[l[rt]]);
			up(l[rt]);
			up(rt);
		} else
		if (q[2]=='T') // get-sum
		{
			int ll,rr;
			scanf("%d%d",&ll,&rr);
			rr+=ll-1;
			prep(ll,rr);
			printf("%d\n",s[r[l[rt]]]);
		} else
		if (q[2]=='X') // max-sum
		{
			printf("%d\n",o[rt]);
		}
	}

	return 0;
}

顺便吐一下槽,c++怎么就没有一个像fp一样简单易上手易用稳定单步调试功能又强大的IDE呢?!用gdb还是蛋疼了一点啊!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值