http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3765
模板题 熟悉基本操作
每次收口袋之后 记得把口袋里的区间splay到根节点 否则慢的出奇
using namespace std;
int getgcd(int a,int b);
struct node;
node* null;
struct node
{
node *ch[2],*fa;
int sz,val[2],gcd[2];
void setc(node* p,int d)
{
ch[d]=p;
p->fa=this;
}
bool getd()
{
return fa->ch[1]==this;
}
void clear()
{
fa=ch[0]=ch[1]=null;
sz=1,val[0]=val[1]=gcd[0]=gcd[1]=0;
}
void pushup()
{
if(this==null) return;
sz=ch[0]->sz+ch[1]->sz+1;
gcd[0]=getgcd(getgcd(ch[0]->gcd[0],ch[0]->val[0]),getgcd(ch[1]->gcd[0],ch[1]->val[0]));
gcd[1]=getgcd(getgcd(ch[0]->gcd[1],ch[0]->val[1]),getgcd(ch[1]->gcd[1],ch[1]->val[1]));
}
};
node pool[300010];
node *root,*tail;
int val[300010],sta[300010];
int n,q;
int getgcd(int a,int b)
{
int t;
if(a==0) swap(a,b);
while(b!=0)
{
t=b;
b=a%b;
a=t;
}
return a;
}
void rotate(node *x)
{
node *f,*ff;
int c,cc;
f=x->fa,ff=x->fa->fa;
c=x->getd(),cc=f->getd();
f->setc(x->ch[!c],c);
x->setc(f,!c);
if(ff->ch[cc]==f) ff->setc(x,cc);
else x->fa=ff;
f->pushup();
}
void splay(node *&root,node *x,node *goal)
{
while(x->fa!=goal)
{
if(x->fa->fa==goal) rotate(x);
else
{
if(x->getd()==x->fa->getd()) rotate(x->fa);
else rotate(x);
rotate(x);
}
}
x->pushup();
if(goal==null) root=x;
}
node *getkth(node *r,int k)
{
node *x=r;
while(x->ch[0]->sz+1!=k)
{
if(x->ch[0]->sz+1>k)
{
x=x->ch[0];
}
else
{
k-=(x->ch[0]->sz+1);
x=x->ch[1];
}
}
return x;
}
void insert(node *&x,node *fa,int val,int sta)
{
x=tail++;
x->clear();
x->fa=fa;
x->val[sta]=val;
}
void build(node *&x,int l,int r,node *fa)
{
int m;
if(l>r) return;
m=(l+r)/2;
x=tail++;
x->clear();
x->fa=fa;
x->val[sta[m]]=val[m];
build(x->ch[0],l,m-1,x);
build(x->ch[1],m+1,r,x);
x->pushup();
}
void init()
{
node* p;
int i;
tail=pool;
null=tail++;
null->fa=null->ch[0]=null->ch[1]=null;
null->sz=null->val[0]=null->val[1]=null->gcd[0]=null->gcd[1]=0;
p=tail++;
p->clear();
root=p;
p=tail++;
p->clear();
root->setc(p,1);
build(root->ch[1]->ch[0],1,n,root->ch[1]);
root->ch[1]->pushup();
root->pushup();
}
int main()
{
node *res;
int i,l,r,x,v,s,ans;
char op[10];
while(scanf("%d%d",&n,&q)!=EOF)
{
for(i=1;i<=n;i++) scanf("%d%d",&val[i],&sta[i]);
init();
while(q--)
{
scanf("%s",op);
if(op[0]=='Q')
{
scanf("%d%d%d",&l,&r,&s);
splay(root,getkth(root,l),null);
splay(root->ch[1],getkth(root,r+2),root);
ans=getgcd(root->ch[1]->ch[0]->gcd[s],root->ch[1]->ch[0]->val[s]);
if(ans==0) printf("-1\n");
else printf("%d\n",ans);
splay(root,root->ch[1]->ch[0],null);
}
else if(op[0]=='I')
{
scanf("%d%d%d",&i,&v,&s);
splay(root,getkth(root,i+1),null);
splay(root->ch[1],getkth(root,i+2),root);
insert(root->ch[1]->ch[0],root->ch[1],v,s);
root->ch[1]->pushup();
root->pushup();
splay(root,root->ch[1]->ch[0],null);
}
else if(op[0]=='D')
{
scanf("%d",&i);
splay(root,getkth(root,i),null);
splay(root->ch[1],getkth(root,i+2),root);
root->ch[1]->ch[0]=null;
root->ch[1]->pushup();
root->pushup();
splay(root,root->ch[1]->ch[0],null);
}
else if(op[0]=='R')
{
scanf("%d",&i);
splay(root,getkth(root,i),null);
splay(root->ch[1],getkth(root,i+2),root);
swap(root->ch[1]->ch[0]->val[0],root->ch[1]->ch[0]->val[1]);
root->ch[1]->pushup();
root->pushup();
splay(root,root->ch[1]->ch[0],null);
}
else
{
scanf("%d%d",&i,&x);
splay(root,getkth(root,i),null);
splay(root->ch[1],getkth(root,i+2),root);
if(root->ch[1]->ch[0]->val[0]!=0) root->ch[1]->ch[0]->val[0]=x;
else root->ch[1]->ch[0]->val[1]=x;
root->ch[1]->pushup();
root->pushup();
splay(root,root->ch[1]->ch[0],null);
}
}
}
return 0;
}