zoukankan      html  css  js  c++  java
  • _bzoj1014 [JSOI2008]火星人prefix【Splay】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1014

    天,写kth()时,把判断条件k <= siz[ch[x][0]]错写成了k <= ch[x][0],RE不停,还爆掉了几个小时,以后写数据结构题一定要头脑清晰啊!

    #include <cstdio>
    #include <cstring>
    
    const int maxn = 300005, base = 131;
    
    int fa[maxn], ch[maxn][2], key[maxn], siz[maxn], root, cnt;
    unsigned long long hash[maxn], poww[maxn];
    int n, m, t1, t2, stk[maxn], top;
    char s[maxn], opr, t3;
    
    inline void pushup(int x) {
    	hash[x] = hash[ch[x][0]] * (poww[siz[ch[x][1]] + 1]) + key[x] * poww[siz[ch[x][1]]] + hash[ch[x][1]];
    	siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
    }
    inline void rotate(int x) {
    	int y = fa[x];
    	if (y == ch[fa[y]][0]) {
    		ch[fa[y]][0] = x;
    	}
    	else {
    		ch[fa[y]][1] = x;
    	}
    	fa[x] = fa[y];
    	int dir = x == ch[y][1];
    	ch[y][dir] = ch[x][dir ^ 1];
    	fa[ch[x][dir ^ 1]] = y;
    	ch[x][dir ^ 1] = y;
    	fa[y] = x;
    	pushup(y);
    	pushup(x);
    }
    inline void splay(int x, int rt) {
    	int p;
    	while (fa[x] != rt) {
    		p = fa[x];
    		if (fa[p] == rt) {
    			rotate(x);
    		}
    		else {
    			if ((p == ch[fa[p]][1]) ^ (x == ch[p][1])) {
    				rotate(x);
    			}
    			else {
    				rotate(p);
    			}
    			rotate(x);
    		}
    	}
    	if (!rt) {
    		root = x;
    	}
    }
    int make_tree(int left, int right) {
    	if (left > right) {
    		return 0;
    	}
    	int rt = (left + right) >> 1;
    	key[rt] = s[rt];
    	ch[rt][0] = make_tree(left, rt - 1);
    	fa[ch[rt][0]] = rt;
    	ch[rt][1] = make_tree(rt + 1, right);
    	fa[ch[rt][1]] = rt;
    	pushup(rt);
    	return rt;
    }
    inline int kth(int k) {
    	int x = root;
    	while (k != siz[ch[x][0]] + 1) {
    		if (k <= siz[ch[x][0]]) {
    			x = ch[x][0];
    		}
    		else {
    			k -= siz[ch[x][0]] + 1;
    			x = ch[x][1];
    		}
    	}
    	return x;
    }
    inline void modify(int root1, int root2) {
    	root1 = kth(root1);
    	root2 = kth(root2);
    	splay(root1, 0);
    	splay(root2, root1);
    }
    inline void ist(int pos, int _key) {
    	modify(pos, pos + 1);
    	++cnt;
    	hash[cnt] = key[cnt] = _key;
    	siz[cnt] = 1;
    	ch[ch[root][1]][0] = cnt;
    	fa[cnt] = ch[root][1];
    	pushup(ch[root][1]);
    	pushup(root);
    }
    /*void ist(int x, int k, int _key) {
    	if (k == siz[ch[x][0]] + 1) {
    		if (ch[x][1]) {
    			top = 0;
    			int i;
    			for (i = ch[x][1]; ch[i][0]; i = ch[i][0]) {
    				stk[top++] = i;
    			}
    			++cnt;
    			ch[i][0] = cnt;
    			fa[cnt] = i;
    			key[cnt] = _key;
    			siz[cnt] = 1;
    			pushup(i);
    			for (i = top - 1; ~i; --i) {
    				pushup(stk[i]);
    			}
    		}
    		else {
    			++cnt;
    			ch[x][1] = cnt;
    			fa[cnt] = x;
    			key[cnt] = _key;
    		}
    		pushup(x);
    		splay(cnt, 0);
    		return;
    	}
    	if (k <= siz[ch[x][0]]) {
    		ist(ch[x][0], k, _key);
    	}
    	else {
    		ist(ch[x][1], k - siz[ch[x][0]] - 1, _key);
    	}
    }*/
    void upd(int x, int k, int _key) {
    	if (k == siz[ch[x][0]] + 1) {
    		key[x] = _key;
    		pushup(x);
    		return;
    	}
    	if (k <= siz[ch[x][0]]) {
    		upd(ch[x][0], k, _key);
    	}
    	else {
    		upd(ch[x][1], k - siz[ch[x][0]] - 1, _key);
    	}
    	pushup(x);
    }
    unsigned long long gethash(int start, int end) {
    	modify(start - 1, end + 1);
    	return hash[ch[ch[root][1]][0]];
    }
    
    int main(void) {
    	//freopen("in.txt", "r", stdin);
    	//freopen("out.txt", "w", stdout);
    	scanf("%s", s + 2);
    	n = strlen(s + 2);
    	s[1] = s[n + 2] = '$';
    	n += 2;
    	cnt = n;
    	poww[0] = 1;
    	for (int i = 1; i < maxn; ++i) {
    		poww[i] = poww[i - 1] * base;
    	}
    	root = make_tree(1, n);
    	scanf("%d", &m);
    	int left, right, mid;
    	while (m--) {
    		while ((opr = getchar()) < 'A');
    		scanf("%d", &t1);
    		++t1;
    		if (opr == 'I') {
    			while ((t3 = getchar()) < 'a');
    			ist(t1, t3);
    			++n;
    		}
    		else if (opr == 'R') {
    			while ((t3 = getchar()) < 'a');
    			upd(root, t1, t3);
    		}
    		else {
    			scanf("%d", &t2);
    			++t2;
    			left = 0;
    			right = n - (t1 > t2? t1: t2);
    			while (left != right) {
    				mid = (left + right + 1) >> 1;
    				if (gethash(t1, t1 + mid - 1) == gethash(t2, t2 + mid - 1)) {
    					left = mid;
    				}
    				else {
    					right = mid - 1;
    				}
    			}
    			printf("%d
    ", left);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    设计模式——观察者模式
    安卓xml动画
    部署在weblogic上的springboot项目上传文件(servlet方式)
    Spring Boot 部署到weblogic 12c
    SpingBoot+Druid监控页面打不开(404)
    DAY49-前端入门-浮动布局案例、z-index、flex布局、响应式布局、过渡与动画
    DAY48-前端入门-文档流、浮动布局、清浮动、流式布局、定位布局
    DAY46-前端入门-组合选择器、标签a_img_list、盒模型、伪类、盒模型布局
    DAY45-前端入门-css的三种引用方式以及优先级、样式与长度颜色、常用样式、css选择器
    DAY44-前端入门-前端三剑客、第一个页面、常用标签、标签分类
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6193539.html
Copyright © 2011-2022 走看看