BZOJ 1500: [NOI2005]维修数列

我的AC率啊 QAQ

一开始看到陈老师300行左右的代码我就淡淡的说了句怎么打的这么多  然后我就打了450行。。。。。

调试了三天  重写了两边 果然是毒瘤Splay。。。。

提取区间打标记 下传标记就好了么。。还是蛮裸的

果然还是自己太弱了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
#define ll int
#define Spaly Splay
char c;
bool flag;
inline void read(ll &a)
{
	toop:
	a=0,flag=false;
	do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
	if(c=='-')flag=true,c=getchar();
	if(c<'0'||c>'9')goto toop;
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
	if(flag)a=-a;
}


struct Node 
{
    Node *lc,*rc,*f;
    ll sum,Maxl,Maxr,Maxm;
    ll change;
	bool same;
	ll same_data;    
    ll data,size;
    inline bool l(){return this->f->lc==this;    }
};
//map<Node*,int>mapp;
Node *empty,*root;
inline void make()
{empty=new Node;empty->f=empty;empty->data=0;empty->size=0;empty->sum=0,empty->Maxl=0;empty->Maxr=0;empty->Maxm=0;empty->rc=empty->lc=empty,empty->same=false;empty->change=0;}
Node *New_Node()
{ Node *tp=new Node; tp->lc=empty;tp->rc=empty;tp->change=0;tp->same=false;tp->size=1;tp->same_data=0;return tp;}

inline void down(Node *a)
{
	if(a==empty)return;
	a->size=a->lc->size+a->rc->size+1;
	if(a->change) 
	{
		swap(a->lc,a->rc);
		swap(a->Maxl,a->Maxr);
		a->lc->change^=1;
		a->rc->change^=1;
		a->change=0;
	}
	if(a->same)
	{
	    if(a->same_data<=0)
	       a->data=a->same_data,a->Maxl=a->same_data,a->Maxm=a->same_data,a->Maxr=a->same_data;
	    else
	       a->data=a->same_data,a->Maxl=a->Maxm=a->Maxr=a->size*a->same_data;
	    a->sum=a->same_data*a->size;
		a->lc->same=a->rc->same=true;
	    a->lc->same_data=a->rc->same_data=a->same_data;
	    a->same=false;
	   return ;
	}
}
int con=0;
int t;
 int tp; 
inline void up_data(Node *a)
{
	if(a==empty)return;
	a->size=a->lc->size+a->rc->size+1;
	t++;
	if(t==8099273)
	   t++,t--;
	down(a);
	if(a->lc->same||a->lc->change)
	 down(a->lc);
	if(a->rc->same||a->rc->change)
	 down(a->rc);
	a->sum=a->lc->sum+a->rc->sum+a->data;
	if(a->size==1)
	   {
	   	 a->Maxl=a->Maxr=a->Maxm=a->sum=a->data;return ;
	   }
	if(a->lc==empty)
		a->Maxl=max(a->data,a->data+a->rc->Maxl);
	else 
	    a->Maxl=max(a->lc->Maxl,a->lc->sum+a->data+a->rc->Maxl),
		a->Maxl=max(a->Maxl,a->lc->sum+(a->data>0?a->data:0));   
	if(a->rc==empty)
        a->Maxr=max(a->data,a->data+a->lc->Maxr);
    else
	  a->Maxr=max(a->rc->Maxr,a->rc->sum+a->data+a->lc->Maxr),
	  a->Maxr=max(a->Maxr,a->rc->sum+(a->data>0?a->data:0));
	
	if(a->lc!=empty&&a->rc!=empty)
	 a->Maxm=max(a->lc->Maxm,a->rc->Maxm);
	else if(a->lc==empty)
	  a->Maxm=a->rc->Maxm;
	else if(a->rc==empty)
	  a->Maxm=a->lc->Maxm;
	a->Maxm=max(a->Maxm,a->Maxl);
    a->Maxm=max(a->Maxm,a->Maxr);
    a->Maxm=max(a->Maxm,a->data);
	if(a->lc!=empty)
	   a->Maxm=max(a->lc->Maxr,a->Maxm),
	   a->Maxm=max(a->lc->Maxr+a->data,a->Maxm);
	if(a->rc!=empty)	    
	   a->Maxm=max(a->rc->Maxl,a->Maxm),
	   a->Maxm=max(a->rc->Maxl+a->data,a->Maxm);
    if(a->rc!=empty&&a->lc!=empty)
       a->Maxm=max(a->Maxm,a->lc->Maxr+a->rc->Maxl+a->data);
/*	a->Maxm=max(a->Maxl,a->Maxr);
	a->Maxm=max(a->Maxm,a->rc->Maxl+a->data+a->lc->Maxr);
	a->Maxm=max(a->Maxm,a->rc->Maxl+(a->data>0?a->data:0));
	a->Maxm=max(a->Maxm,(a->data>0?a->data:0)+a->lc->Maxr);
	a->Maxm=max(a->Maxm,a->data);
	a->Maxm=max(a->Maxm,a->lc->Maxm);
	a->Maxm=max(a->Maxm,a->rc->Maxm);*/
}
inline void lc_change(Node *a)
{
	Node *newf;
	/*up_data(a->f);
	up_data(a); 
	*/
	if(a==root)
	   {up_data(a);return ;	   }
	if(a->f==root)
	   root=a,newf=a;
	else if(a->f->l())
	   a->f->f->lc=a,newf=a->f->f;
	else
	   a->f->f->rc=a,newf=a->f->f;
	a->rc->f=a->f;
	a->f->lc=a->rc;   
	a->f->f=a;
	a->rc=a->f;
	a->f=newf;
	up_data(a->rc);
	up_data(a);
}
inline void rc_change(Node *a)
{
	Node *newf;
	/*up_data(a->f);
	up_data(a);
	*/
	if(a==root)
	   {up_data(a);return ;	   }
	if(a->f==root)
	   root=a,newf=a;
	else if(a->f->l())
	   a->f->f->lc=a,newf=a->f->f;
	else
	   a->f->f->rc=a,newf=a->f->f;
	a->lc->f=a->f;
	a->f->rc=a->lc;   
	a->f->f=a;
	a->lc=a->f;
	a->f=newf;
	up_data(a->lc);
	up_data(a);
}
inline void Change(Node *a)
{
       if(a->f->change||a->f->same)down(a->f);
       if(a->change||a->same)down(a);
    a->l()?lc_change(a):rc_change(a);
}
inline void Twice_Change(Node *a)
{
       if(a->f->f->change||a->f->f->same)down(a->f->f);
       if(a->f->change||a->f->same)down(a->f);
       if(a->change||a->same)down(a);
    if(a->l()==a->f->l())Change(a->f),Change(a);	else Change(a),Change(a);
}
inline void Splay(Node *a)
{
   while(a->f->f!=a->f)Twice_Change(a);
   while(a->f!=a)Change(a);
}

inline void Splay2(Node *a)
{
   while(a->f->f->f!=a->f->f) Twice_Change(a);
   while(a->f->f!=a->f)Change(a);
}
ll at[1000001];
ll n,m;
Node *build(Node *a,ll l,ll r)
{
	ll lc,rc,x;
	x=(l+r)>>1;
	a->data=at[x];
	a->size=r-l+1;
	Node *res=a;
	if(l<x)
	   a->lc=New_Node(),a->lc->f=a,build(a->lc,l,x-1);
	if(r>x)
	   a->rc=New_Node(),a->rc->f=a,res=build(a->rc,x+1,r);
    up_data(a);
    return res;
}
Node *search(Node *a,ll rank)
{
	up_data(a);
	if(rank==1)
	   if(a->lc!=empty)return search(a->lc,rank);
	   else return a;
	else
	   if(rank<=a->lc->size)
	      return search(a->lc,rank);
       else if(rank==1+a->lc->size)return a;
       else return search(a->rc,rank-a->lc->size-1);
}
void era(Node *a)
{
	if(a->lc!=empty)
	   era(a->lc);
    if(a->rc!=empty)
	   era(a->rc);
	 delete a;	
}
inline void insert(ll begin,ll len)
{
	for(ll i=1;i<=len;i++)
	  read(at[i]);
	Node *t,*a,*Neww=New_Node();
	t=build(Neww,1,len);
	if(begin==0)
	 {
	 	root->f=t;
	 	t->rc=root;
	 	Neww->f=Neww;
	 	root=Neww;
	 	Splay(t->rc==empty?t:t->rc);
	 	con+=len;
	 	return ;
	 }
	 if(begin==con)
	  {
	       a=search(root,begin);
	       a->rc=Neww;
	       Neww->f=a;
	       Splay(t);
		   con+=len;return ;
	  }
	up_data(Neww);
	a=search(root,begin);
	t->rc=a->rc;
    a->rc->f=t;
    a->rc=Neww;
    Neww->f=a;
	Splay(t->rc==empty?t:t->rc);
	con+=len;
}
#define search(j) search(root,j)
inline void del()
{
	ll j,con2,k;
	read(j),read(con2);
	Node *head=NULL,*tail=NULL;
	if(j>1)
	 head=search(j-1);
	if(j+con2-1!=con)
	   tail=search(j+con2);
	if(!head&&!tail)
      {
      	con=0;era(root);
      	root=empty;
        con=0;
	    return ;
	  }
    if(!head)
      {
      	Splay(tail);
        era(tail->lc);
        tail->lc=empty;
        up_data(tail);
		con-=con2;
		return;
	  }
    if(!tail)
      {
      	Splay(head);
      	era(head->rc);
      	head->rc=empty;
      	up_data(head);
		con-=con2;
      	return ;
      }
	Splay(head);Splay2(tail);
	era(tail->lc);
	tail->lc=empty;
	//up_data(tail);
	Splay(tail);
    con-=con2;
}
inline void same()
{
	ll j,con2,k;
	read(j),read(con2);
	Node *head=NULL,*tail=NULL;
	if(j>1)
	 head=search(j-1);
	if(j+con2-1!=con)
	   tail=search(j+con2);
	if(!head&&!tail)
	    {
	    	root->same=true;
	    	read(root->same_data);
	    	return;
	    }
    if(!head)
        {
        	Spaly(tail);
        	tail->lc->same=true;;
        	read(tail->lc->same_data);
        	Spaly(tail->lc);
        	return ;
        }
    if(!tail)
        {
        	Spaly(head);
        	head->rc->same=true;
            read(head->rc->same_data);
            Spaly(head->rc);
            return ;
		}
	Splay(head);Splay2(tail);
	tail->lc->same=true;
	read(tail->lc->same_data);
//	up_data(tail->lc);
	Splay(tail->lc);
}

inline void rev()
{
	ll j,con2,k;
	read(j),read(con2);
	Node *head=NULL,*tail=NULL;
	if(j>1)
	 head=search(j-1);
	if(j+con2-1!=con)
	   tail=search(j+con2);
	if(!head&&!tail)
	    {
	    	root->change^=1;
	    	return;
	    }
    if(!head)
        {
        	Spaly(tail);
        	tail->lc->change^=1;;
        	Spaly(tail->lc);
        	return ;
        }
    if(!tail)
        {
        	Spaly(head);
        	head->rc->change^=1;
            Spaly(head->rc);
            return ;
		}
	Splay(head);Splay2(tail);
    up_data(tail->lc);
	tail->lc->change^=1;
	Splay(tail->lc);
//	up_data(root);
}
inline void print(int a)
{
	if(a==-6)
	   a++,a--;
	if(a<0)a=-a,putchar('-');
	if(a<10){putchar('0'+a),putchar('\n');return ;}
	long long base=1;
	while(base<=a)
	 base=(base<<3)+(base<<1);
	base/=10;
	while(base)
	putchar('0'+a/base),a%=base,base/=10;
	putchar('\n');
}
inline void query()
{
	ll j,con2,k;
	read(j),read(con2);
	Node *head=NULL,*tail=NULL;
	if(j>1)
	 head=search(j-1);
	if(j+con2-1!=con)
	   tail=search(j+con2);
	if(!head&&!tail)
	    {
	    	up_data(root);
			//printf("%d\n",root->sum);
			print(root->sum);
	    	return;
	    }
    if(!head)
        {
        	Spaly(tail);
//        	printf("%d\n",tail->lc->sum);
        	print(tail->lc->sum);
			return ;
        }
    if(!tail)
        {
        	Spaly(head);
//        	printf("%d\n",head->rc->sum);
            print(head->rc->sum);
			return ;
		}
	Splay(head);Splay2(tail);
//    printf("%d\n",tail->lc->sum);
    print(tail->lc->sum);
}
inline void max_sum()
{	up_data(root),
//printf("%d\n",root->Maxm);
   print(root->Maxm);
}
int main()
{
	make();
	read(n),read(m);
	ll i,j,k,l;
	root=empty;
	insert(0,n); 
    for(i=1;i<=m;i++)
	   {
	   	tp++;
	   	if(tp==19418)
	   	    tp++,tp--;
		    do c=getchar();while(c!='I'&&c!='D'&&c!='K'&&c!='R'&&c!='G'&&c!='U');
	   	 if(c=='I')
	   	     read(j),read(k),insert(j,k);//,print(root);
	   	 else if(c=='D')
	   	     del();//,print(root);
	   	 else if(c=='K')
	   	     same();
	   	 else if(c=='R')
	   	      rev();
	     else if(c=='G')
	          query();
	     else max_sum();
	   }
	   	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值