ACM模版
Treap
long long gcd(long long a, long long b)
{
if (b == 0)
{
return a;
}
else
{
return gcd(b, a % b);
}
}
const int MAXN = 300010;
int num[MAXN], st[MAXN];
struct Treap
{
int tot1;
int s[MAXN], tot2; // 内存池和容量
int ch[MAXN][2];
int key[MAXN], size[MAXN];
int sum0[MAXN], sum1[MAXN];
int status[MAXN];
void Init()
{
tot1 = tot2 = 0;
size[0] = 0;
ch[0][0] = ch[0][1] = 0;
sum0[0] = sum1[0] = 0;
return ;
}
bool random(double p)
{
return (double)rand() / RAND_MAX < p;
}
int newnode(int val, int _status)
{
int r;
if (tot2)
{
r = s[tot2--];
}
else
{
r = ++tot1;
}
size[r] = 1;
key[r] = val;
status[r] = _status;
ch[r][0] = ch[r][1] = 0;
sum0[r] = sum1[r] = 0; // 需要push_up
return r;
}
void del(int r)
{
if (!r)
{
return ;
}
s[++tot2] = r;
del(ch[r][0]);
del(ch[r][1]);
return ;
}
void push_up(int r)
{
int lson = ch[r][0], rson = ch[r][1];
size[r] = size[lson] + size[rson] + 1;
sum0[r] = (int)gcd(sum0[lson], sum0[rson]);
sum1[r] = (int)gcd(sum1[lson], sum1[rson]);
if (status[r] == 0)
{
sum0[r] = (int)gcd(sum0[r], key[r]);
}
else
{
sum1[r] = (int)gcd(sum1[r],key[r]);
}
return ;
}
void merge(int &p, int x, int y)
{
if (!x || !y)
{
p = x | y;
}
else if (random((double)size[x] / (size[x] + size[y])))
{
merge(ch[x][1], ch[x][1], y);
push_up(p = x);
}
else
{
merge(ch[y][0], x, ch[y][0]);
push_up(p = y);
}
return ;
}
void split(int p, int &x, int &y, int k)
{
if (!k)
{
x = 0;
y = p;
return ;
}
if (size[ch[p][0]] >= k)
{
y = p;
split(ch[p][0], x, ch[y][0], k);
push_up(y);
}
else
{
x = p;
split(ch[p][1], ch[x][1], y, k - size[ch[p][0]] - 1);
push_up(x);
}
return ;
}
void build(int &p, int l, int r)
{
if (l > r)
{
return ;
}
int mid = (l + r) / 2;
p = newnode(num[mid], st[mid]);
build(ch[p][0], l, mid - 1);
build(ch[p][1], mid + 1, r);
push_up(p);
return ;
}
void debug(int root)
{
if (root == 0)
{
return ;
}
printf("%d 左儿子:%d 右儿子: %d size = %d key = %d\n", root, ch[root][0], ch[root][1], size[root], key[root]);
debug(ch[root][0]);
debug(ch[root][1]);
}
};
Treap T;
char op[10];
int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n, q;
while (scanf("%d%d", &n, &q) == 2)
{
int root = 0;
T.Init();
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &num[i], &st[i]);
}
T.build(root, 1, n);
while (q--)
{
scanf("%s", op);
if (op[0] == 'Q')
{
int l, r, s;
scanf("%d%d%d", &l, &r, &s);
int x, y, z;
T.split(root, x, z, r);
T.split(x, x, y, l - 1);
if (s == 0)
{
printf("%d\n", T.sum0[y] == 0 ? -1 : T.sum0[y]);
}
else
{
printf("%d\n", T.sum1[y] == 0 ? -1 : T.sum1[y]);
}
T.merge(x, x, y);
T.merge(root, x, z);
}
else if (op[0] == 'I')
{
int v, s, loc;
scanf("%d%d%d", &loc, &v, &s);
int x, y;
T.split(root, x, y, loc);
T.merge(x, x, T.newnode(v,s));
T.merge(root, x, y);
}
else if (op[0] == 'D')
{
int loc;
scanf("%d", &loc);
int x, y, z;
T.split(root, x, z, loc);
T.split(x, x, y, loc - 1);
T.del(y);
T.merge(root, x, z);
}
else if(op[0] == 'R')
{
int loc;
scanf("%d", &loc);
int x, y, z;
T.split(root, x, z, loc);
T.split(x, x, y, loc - 1);
T.status[y] = 1 - T.status[y];
T.push_up(y);
T.merge(x, x, y);
T.merge(root, x, z);
}
else
{
int loc, v;
scanf("%d%d", &loc, &v);
int x, y, z;
T.split(root, x, z, loc);
T.split(x, x, y, loc - 1);
T.key[y] = v;
T.push_up(y);
T.merge(x, x, y);
T.merge(root, x, z);
}
}
}
return 0;
}