#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
long long wei[100010];
char s[100010];
int n;
void init()//这是针对本题的操作并无通用性
{
wei[0] = 1;
for (int i = 1; i < 100010; i++)
{
wei[i] = (wei[i - 1] * 26) % 2333333333;
}
}
//写splaytree的时候关键是要和0点撇清关系。。。
struct splaytree//从这开始是splay 模板
{
int fa, son[2], size, worth,num;
unsigned long long value;
splaytree()
{
fa = son[0] = son[1] = size = worth = value = 0;
}
};
splaytree node[250010];
void update(splaytree &k)
{
k.size = 1 + node[k.son[0]].size + node[k.son[1]].size;
k.value =(k.worth*wei[node[k.son[0]].size] + node[k.son[0]].value + node[k.son[1]].value*wei[node[k.son[0]].size + 1]) % 2333333333;
}
int link(splaytree &k, int d, int kid)
{
k.son[d] = kid;
if (kid)//撇清关系
node[kid].fa =k.num;
return k.num;
}
int getlr(splaytree &k)
{
return node[k.fa].son[1] ==k.num;
}
int tot = 0;
int root;
int newnode(int worth)
{
tot++;
node[tot].worth = node[tot].value = worth;
node[tot].size = 1;
node[tot].num = tot;
return tot;
}
void rot(int x)
{
int fa = node[x].fa;
int gfa = node[fa].fa;
int dx = getlr(node[x]);
int dfa =getlr(node[fa]);
link(node[x],dx ^ 1,link(node[fa],dx, node[x].son[dx ^ 1]));
if (gfa)
link(node[gfa],dfa, x);
else
node[x].fa = gfa;
update(node[fa]);
}
void newsplay(int x,int to)
{
while (node[x].fa&&node[x].fa!=to)//这易错因为node[x].fa又阔能为空然后to不空这样就有bug 了。。。
{
if (node[node[x].fa].fa!=to)
getlr(node[node[x].fa]) == getlr(node[x]) ? rot(node[x].fa) : rot(x);
rot(x);
}
update(node[x]);
if(to==0)
root = x;//这是易错的,因为如果不是转到root是不能修改root的
}
int build(int l, int r)
{
//cout << "sds" << endl;
if (l > r)
return 0;
int mid = (l + r) >> 1;
int num = newnode(s[mid]-'a');
link(node[num],0, build(l, mid - 1));
link(node[num],1, build(mid + 1, r));
update(node[num]);
if (l == 0 && r == n)
root = num;
return num;
}
int find(int size)
{
int temp = root;
while (temp != 0)
{
if (node[node[temp].son[0]].size >= size)
temp = node[temp].son[0];
else
{
size -= node[node[temp].son[0]].size;
if (size == 1)return temp;
size--;
temp = node[temp].son[1];
}
}
return 0;
}//这结束模板
void insert(int pos,char kid)//以下是针对本题的操作
{
int kidnum = newnode(kid - 'a');
if (pos == 0 || pos == node[root].size)
{
int k;
pos == 0 ? (k = find(1)) : (k = find(node[root].size));
newsplay(k, 0);
pos == 0 ? link(node[k],0, kidnum) : link(node[k],1, kidnum);
update(node[k]);
}
else
{
int l = pos;
int r = pos + 1;
int nodel = find(l);
int noder = find(r);
newsplay(nodel, 0);
newsplay(noder, root);
link(node[noder],0, kidnum);
for (int i = noder; i != 0; i = node[i].fa)
update(node[i]);
}
}
unsigned long long findvalue(int l, int r)
{
if (l == 1&&r!=node[root].size)
{
int end = find(r + 1);
newsplay(end, 0);
return node[node[root].son[0]].value;
}
if (r == node[root].size&&l!=1)
{
int begin = find(l - 1);
newsplay(begin, 0);
return node[node[root].son[1]].value;
}
if (l == 1 && r == node[root].size)
{
return node[root].value;
}
l = find(l - 1);
r = find(r +1);
newsplay(l, 0);
newsplay(r, root);
return node[node[r].son[0]].value;
}
int com(int first, int second)
{
int l = 0;
int r = min(node[root].size - first + 1, node[root].size - second + 1);
int mid = r;
//cout << "r:" << r << " " << "l:" << l << endl;
while ((r-l)>1)
{
unsigned long long p1 = findvalue(first, first + mid - 1);
unsigned long long p2 = findvalue(second, second + mid - 1);
if (p1 == p2)
l = mid;
else
r = mid - 1;
mid = (l + r) >> 1;
}
unsigned long long p1 = findvalue(first, first + r- 1);
unsigned long long p2 = findvalue(second, second + r - 1);
if (p1 != p2)
return l;
else
return r;
}
void change(int pos, char worth)
{
pos = find(pos);
node[pos].worth = worth - 'a';
update(node[pos]);
newsplay(pos, 0);
}
int main()
{
int i;
for ( i = 0;; i++)
{
scanf("%c", &s[i]);
if (s[i] == '\n')
break;
}
n = i - 1;
init();
build(0, n);
int m;
scanf("%d", &m);
for (int i = 0; i < m; i++)
{
// cout << i << endl;
char c;
getchar();
scanf("%c", &c);
if (c == 'Q')
{
int l, r;
scanf("%d%d", &l, &r);
int ans = com(l, r);
printf("%d\n", ans);
}
if (c == 'R')
{
int l;
char c;
scanf("%d", &l);
getchar();
scanf("%c", &c);
change(l, c);
}
if (c == 'I')
{
int l;
char c;
scanf("%d", &l);
getchar();
scanf("%c", &c);
insert(l, c);
}
}
return 0;
}
bzoj 1014伸展树 模板题
最新推荐文章于 2021-01-09 17:41:56 发布