单旋递归大常数splay

来源:互联网 发布:云计算岗位 编辑:程序博客网 时间:2024/04/28 09:45

show show我的单旋递归大常数splay。

很蛋疼的rotate把lc和rc两个数组进去了。

题目:2010省队集训,unstable不稳定匹配。


#include <stdio.h>#include <memory.h>#include <stdlib.h>#include <math.h>#include <time.h>#include <assert.h>#define maxn 1150000#define maxm 1150000#define prime 1000000007ll#define unit 13499267949257065399ull#define maxrange 11000typedef 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;}