您的位置:首页 > 其它

BZOJ3323: [Scoi2013]多项式的运算

2016-02-05 14:40 288 查看
很水的一道Splay维护题

好吧我其实被卡的很惨。。。

常数大的要死

注意一下放标的顺序与时机这样可以大大减小常数

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
char c;
#define ll long long
inline void read(ll &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
const
ll mod=20130426;
struct Node
{
Node *lc,*rc,*f;
ll DeBug;
ll add_delta,k_delta;
ll ax_delta;
ll k,ax;
inline bool l(){return f->lc==this;}
inline bool flag(){return add_delta||k_delta!=1||ax_delta;}
inline friend Node operator +=(Node &a,Node b)
{
a.k+=b.k;
return a;
}
}Tree[100002];
Node *root,*empty;

Node *build(ll l,ll r)
{
if(r<l)return empty;
Node *tp=&Tree[(l+r)>>1];
tp->lc=build(l,((l+r)>>1)-1),tp->lc->f=tp,
tp->rc=build(((l+r)>>1)+1,r),tp->rc->f=tp;
return tp;
}

inline void begin()
{
empty=new Node;
empty->lc=empty;
empty->rc=empty;
for(ll i=0;i<=100001;i++)
Tree[i].ax=Tree[i].DeBug=i,Tree[i].k=0,Tree[i].add_delta=Tree[i].ax_delta=0,Tree[i].k_delta=1;
root=build(0,100001);
root->f=root;
Tree[100001].ax=1ll<<62;
}
int ttp;
inline void Mod(Node *a)
{
if(a==empty)return;
ttp+=3;
a->k%=mod;a->add_delta%=mod;a->k_delta%=mod;
}
void pushdown(Node *a)
{
a->lc->add_delta=a->lc->add_delta*a->k_delta+a->add_delta;
a->rc->add_delta=a->rc->add_delta*a->k_delta+a->add_delta;
a->lc->k_delta=a->lc->k_delta*a->k_delta;
a->rc->k_delta=a->rc->k_delta*a->k_delta;
a->k=a->k*a->k_delta+a->add_delta;
a->lc->ax_delta+=a->ax_delta;
a->rc->ax_delta+=a->ax_delta;
a->ax+=a->ax_delta;
a->ax_delta=0;
a->k_delta=1;
a->add_delta=0;
Mod(a->lc),Mod(a->rc),Mod(a);
}
inline void Lc(Node *a)
{
Node *f;
if(a->f==root)
f=a,root=a;
else
if(a->f->l())
a->f->f->lc=a,f=a->f->f;
else a->f->f->rc=a,f=a->f->f;
a->rc->f=a->f;
a->f->lc=a->rc;
a->f->f=a;
a->rc=a->f;
a->f=f;
}
inline void Rc(Node *a)
{
Node *f;
if(a->f==root)
f=a,root=a;
else
if(a->f->l())
a->f->f->lc=a,f=a->f->f;
else a->f->f->rc=a,f=a->f->f;
a->lc->f=a->f;
a->f->rc=a->lc;
a->f->f=a;
a->lc=a->f;
a->f=f;
}
inline void Change(Node *a)
{a->l()?Lc(a):Rc(a);}
inline void TwiChange(Node *a)
{a->l()==a->f->l()?Change(a->f):Change(a);Change(a);}
inline void Rotato(Node *a)
{
while(a->f!=root)TwiChange(a);
if(a!=root)Change(a);
}
inline void Rotato2(Node *a)
{
while(a->f->f!=root)TwiChange(a);
if(a->f!=root)Change(a);
}
Node* FindPre(ll ax,Node *tp)
{
Node *res;
if(tp==empty)return tp;
if(tp->flag())pushdown(tp);
if(tp->ax>=ax)return (res=FindPre(ax,tp->lc))==empty?empty:res;
return (res=FindPre(ax,tp->rc))==empty?tp:res;
}
Node* FindAft(ll ax,Node *tp)
{
Node *res;
if(tp==empty)return tp;
if(tp->flag())pushdown(tp);
if(tp->ax>ax)return (res=FindAft(ax,tp->lc))==empty?tp:res;
return (res=FindAft(ax,tp->rc))==empty?empty:res;
}
inline Node* Div(ll l,ll r)
{

Node *L;
if((L=FindPre(l,root))!=empty)
{
Rotato(L),Rotato2(FindAft(r,root));
return root->rc->lc;
}
else
{
Rotato(FindAft(r,root));
return root->lc;
}
}
inline void Oper1()
{
ll v,l,r;
read(l),read(r),read(v);
Node *R=Div(l,r);
R->k_delta*=v;
R->add_delta*=v;
Mod(R);
}
inline void Oper2()
{
ll v,l,r;
read(l),read(r),read(v);
Div(l,r)->add_delta+=v;
}
void Insert(Node *Cache,Node *tp)
{
if(tp->flag())pushdown(tp);
if(Cache->ax<tp->ax)
if(tp->lc==empty)
Cache->f=tp,tp->lc=Cache;
else
Insert(Cache,tp->lc);
else
if(tp->rc==empty)
Cache->f=tp,tp->rc=Cache;
else
Insert(Cache,tp->rc);
}
inline void Oper3()
{
ll l,r;
read(l),read(r);
Div(l,r)->ax_delta++;
Node *tp=FindAft(r,root);
Node *tp2=FindPre(r+2,root);
tp2->k+=tp->k;
while(tp->lc!=empty||tp->rc!=empty)
tp->lc!=empty?Change(tp->lc):Change(tp->rc);
(tp->l()?tp->f->lc:tp->f->rc)=empty;
tp->ax=l;
tp->k=0;
tp->k_delta=1;
tp->add_delta=0;
tp->ax_delta=0;
Insert(tp,root);
}
ll Query(ll a,ll &tmp,Node *tp)
{
if(tp==empty)return 0;
if(tp->flag())pushdown(tp);
ll res=Query(a,tmp,tp->lc);
res+=tp->k*1ll*tmp;
tmp=(a*1ll*tmp)%mod;
return res=(res+Query(a,tmp,tp->rc))%mod;
}
inline void Oper4()
{
ll v,tp=1;
read(v);
Rotato(&Tree[100001]);
printf("%lld\n",Query(v,tp,root->lc));
}
ll n;
int main()
{
begin();
read(n);
while(n--)
{

do c=getchar();while(c!='a'&&c!='q'&&c!='m');
if(c=='a')
Oper2();
else if(c=='m')
{
c=getchar();c=getchar();c=getchar();
if(c=='x')Oper3();
else Oper1();
}
else Oper4();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: