show show我的单旋递归大常数splay。
很蛋疼的rotate把lc和rc两个数组进去了。
题目:2010省队集训,unstable不稳定匹配。
#include
#include
#include
#include
#include
#include
#define maxn 1150000
#define maxm 1150000
#define prime 1000000007ll
#define unit 13499267949257065399ull
#define maxrange 11000
typedef unsigned long long ull;
typedef struct
{
int size, rev;
ull key, hfor, hbak;
} node;
ull dest[maxm];
node x[maxn];
int lc[maxn];
int rc[maxn];
ull R[maxrange];
ull U[maxn];
ull P[maxn];
int *ptr[2] = {lc, rc};
int n, m, root, xtop;
inline void update (int p)
{
node *y = x + p, *l = x + lc[p], *r = x + rc[p];
y->size = l->size + r->size + 1;
y->hfor = l->hfor + P[l->size] * y->key + P[l->size + 1] * r->hfor;
y->hbak = r->hbak + P[r->size] * y->key + P[r->size + 1] * l->hbak;
}
inline void swap (int *i, int *j){int t = *i; *i = *j; *j = t;}
inline void swapull (ull *i, ull *j){ull t = *i; *i = *j; *j = t;}
inline int min (int i, int j){return i < j ? i : j;}
inline ull hash (int l, int r){return (dest[r] - dest[l]) * U[l];}
inline void mark_rev (int p)
{
swap (&lc[p], &rc[p]);
swapull (&x[p].hfor, &x[p].hbak);
x[p].rev ^= 1;
}
inline void push_rev (int p)
{
mark_rev (lc[p]), mark_rev (rc[p]), x[p].rev = 0;
}
void rotate (int *t, int *lc, int *rc)
{
int k = lc[*t];
lc[*t] = rc[k];
rc[k] = *t;
update (*t);
*t = k;
}
void splay (int *t, int k)
{
if (x[*t].rev)
push_rev (*t);
int s = x[lc[*t]].size;
if (s > k)
splay (lc + *t, k), rotate (t, lc, rc);
else if (s < k)
splay (rc + *t, k - s - 1), rotate (t, rc, lc);
}
inline void inteval (int l, int r){splay (&root, r + 1), update (root), splay (&root, l - 1), update (root);}
int query (int A, int B)
{
--A, --B;
splay (&root, A), update (root);
int t = rc[root], s, ret = 0;
for (; t; )
{
if (x[t].rev)
push_rev (t);
s = x[lc[t]].size + 1;
if (B + s <= m && x[lc[t]].hfor + P[s - 1] * x[t].key == hash (B, B + s))
ret += s, t = rc[t], B += s;
else
t = lc[t];
}
return ret;
}
int build (int l, int r)
{
int mid = (l + r) >> 1, t = mid + 2;
if (l != mid) lc[t] = build (l, mid - 1);
if (r != mid) rc[t] = build (mid + 1, r);
update (t);
return t;
}
int main()
{
FILE *fin = fopen ("unstable.in" , "r");
FILE *fout = fopen ("unstable.out", "w");
int i, s1, s2, s3, s4, k, p;
char cmd[50];
srand (time (0));
for (i = 0; i < maxrange; ++i)
R[i] = (ull)rand () << 32 | rand ();
for (P[0] = U[0] = 1, i = 1; i < maxm; ++i)
P[i] = P[i - 1] * prime, U[i] = U[i - 1] * unit;
fscanf (fin, "%d%d", &n, &m);
for (i = 1; i <= n; ++i)
fscanf (fin, "%d", &s1), x[i + 2] = (node){1, 0, R[s1]};
for (i = 1; i <= m; ++i)
fscanf (fin, "%d", &s1), dest[i] = dest[i - 1] + R[s1] * P[i - 1];
root = 1, xtop = n + 2;
rc[1] = 2, lc[2] = build (1, n), update (2), update (1);
fscanf (fin, "%d%d%d%d", &s1, &s2, &s3, &s4);
inteval (1, 1);
for (i = s1 + s2 + s3 + s4; i; --i)
{
fscanf (fin, "%s", cmd);
switch (cmd[0])
{
case 'I':
fscanf (fin, "%d%d", &k, &p);
inteval (k, k - 1), x[++xtop] = (node){1, 0, R[p], R[p], R[p]};
lc[rc[root]] = xtop; break;
case 'D':
fscanf (fin, "%d", &k);
inteval (k, k), lc[rc[root]] = 0; break;
case 'R':
fscanf (fin, "%d%d", &k, &p);
if (k > p) swap (&k, &p);
inteval (k, p);
mark_rev (lc[rc[root]]); break;
case 'Q':
fscanf (fin, "%d%d", &k, &p);
fprintf (fout, "%d\n", query (k, p));
break;
}
update (rc[root]), update (root);
}
fclose (fin);
fclose (fout);
return 0;
}