[ZOJ 3765 Lights] Splay
来源:互联网 发布:火影忍者手游pk网络卡 编辑:程序博客网 时间:2024/05/23 19:14
[ZOJ 3765 Lights] Splay
分类:Data Structure
Splay
1. 题目链接
[ZOJ 3765 Lights]
2. 题意描述
有一个长度为
序列中每个元素有两个属性,value和status。有以下几种操作。
- 查询区间
[L,R] 范围内状态为status 的数的value 的gcd; - 第
i 个元素后面插入一个元素 - 删除第
i 个元素 - 将第
i 个元素的status 取反 - 修改第
i 个元素的value
数据范围:
3. 解题思路
裸的Splay模板。只需要维护
注意一下,后面的操作中,会生成一些节点,所以要降数组大小开到300000。
试了一下单旋和双旋,在这个题目里面没有什么区别。
不过,正式比赛的时候千万不要这么zuo,在链式的情况下,单旋之后依旧会是一条链,而双旋之后,链会变成一棵树。只有双旋,才能保证均摊复杂度为
4. 实现代码
#include <bits/stdc++.h>using namespace std;typedef long long LL;typedef long double LB;typedef pair<int, int> PII;typedef pair<LL, LL> PLL;typedef vector<int> VI;const int INF = 0x3f3f3f3f;const LL INFL = 0x3f3f3f3f3f3f3f3fLL;const double eps = 1e-8;const double PI = acos(-1.0);#define Key_value ch[ch[root][1]][0]const int MAXN = 300010;int pre[MAXN], ch[MAXN][2], sz[MAXN];int root, tot1;int gcd[MAXN][2], stat[MAXN], key[MAXN];int s[MAXN], tot2; //内存池和容量int a[MAXN], b[MAXN];int n, q;//debug部分**********************************void Treavel(int x) { if(x) { Treavel(ch[x][0]); printf("root: %2d: lch %2d rch %2d fa %2d size= %2d\n", x, ch[x][0], ch[x][1], pre[x], sz[x]); Treavel(ch[x][1]); }}void debug() { printf("root:%d\n", root); Treavel(root);}//以上是debug部分**************************************inline void NewNode(int &r, const int& father, const int& ax, const int& bx) { if(tot2) r = s[tot2--]; //取的时候是tot2--,存的时候就是++tot2 else r = ++tot1; pre[r] = father; ch[r][0] = ch[r][1] = 0; key[r] = ax; stat[r] = bx; gcd[r][bx] = ax; gcd[r][!bx] = 0; sz[r] = 1;}inline int m_gcd(const int& ax, const int& bx) { if(ax == 0 && bx == 0) return 0; if(ax == 0) return bx; if(bx == 0) return ax; return __gcd(ax, bx);}inline void pushUp(const int&r) { int lson = ch[r][0], rson = ch[r][1]; sz[r] = sz[lson] + sz[rson] + 1; gcd[r][0] = gcd[r][1] = 0; gcd[r][0] = m_gcd(gcd[lson][0], gcd[rson][0]); gcd[r][1] = m_gcd(gcd[lson][1], gcd[rson][1]); gcd[r][stat[r]] = m_gcd(gcd[r][stat[r]], key[r]);}void Build(int &x, int l, int r, int father) { if(l > r) return; int mid = (l + r) / 2; NewNode(x, father, a[mid], b[mid]); Build(ch[x][0], l, mid - 1, x); Build(ch[x][1], mid + 1, r, x); pushUp(x);}void Init() { root = tot1 = tot2 = 0; ch[root][0] = ch[root][1] = sz[root] = pre[root] = 0; stat[0] = gcd[root][0] = gcd[root][1] = key[root] = 0; NewNode(root, 0, 0, 0); NewNode(ch[root][1], root, 0, 0); for(int i = 0; i < n; i++) scanf("%d %d", &a[i], &b[i]); Build(Key_value, 0, n - 1, ch[root][1]); pushUp(ch[root][1]); pushUp(root);}//旋转,0为左旋,1为右旋void Rotate(int x, int kind) { int y = pre[x]; ch[y][!kind] = ch[x][kind]; pre[ch[x][kind]] = y; if(pre[y]) ch[pre[y]][ch[pre[y]][1] == y] = x; pre[x] = pre[y]; ch[x][kind] = y; pre[y] = x; pushUp(y);}// 将r放到goal下面,, 双旋void Splay(int r, int goal) { while(pre[r] != goal) { if(pre[pre[r]] == goal) { Rotate(r, ch[pre[r]][0] == r); } else { int y = pre[r]; int kind = ch[pre[y]][0] == y; if(ch[y][kind] == r) { //zig-zag zag-zig Rotate(r, !kind); Rotate(r, kind); } else { //zig-zig zag-zag Rotate(y, kind); Rotate(r, kind); } } } pushUp(r); if(goal == 0) root = r;}// 将r放到goal下面,, 单旋/*void Splay(int r, int goal) { while(pre[r] != goal) { Rotate(r, ch[pre[r]][0] == r); } pushUp(r); if(goal == 0) root = r;}*/int Kth(int r, int k) { int t = sz[ch[r][0]] + 1; if(t == k) return r; if(t > k) return Kth(ch[r][0], k); else return Kth(ch[r][1], k - t);}void Insert(int pos, int ax, int bx) { Splay(Kth(root, pos + 1), 0); Splay(Kth(root, pos + 2), root); NewNode(Key_value, ch[root][1], ax, bx); pushUp(ch[root][1]); pushUp(root);}void erase(int r) { if(!r)return; s[++tot2] = r; erase(ch[r][0]); erase(ch[r][1]);}void Delete(int pos) { Splay(Kth(root, pos), 0); Splay(Kth(root, pos + 2), root); erase(Key_value); pre[Key_value] = 0; Key_value = 0; pushUp(ch[root][1]); pushUp(root);}void Update_R(int pos) { Splay(Kth(root, pos), 0); Splay(Kth(root, pos + 2), root); stat[Key_value] ^= 1; pushUp(Key_value); pushUp(ch[root][1]); pushUp(root);}void Update_M(int pos, int a) { Splay(Kth(root, pos), 0); Splay(Kth(root, pos + 2), root); key[Key_value] = a; pushUp(Key_value); pushUp(ch[root][1]); pushUp(root);}int Get_Ans(int L, int R, int bx) { Splay(Kth(root, L), 0); Splay(Kth(root, R + 2), root); return gcd[Key_value][bx];}int main() {#ifdef ___LOCAL_WONZY___ freopen("input.txt", "r", stdin);#endif // ___LOCAL_WONZY___ int L, R, ax, bx, px, ans; char op[10]; while(scanf("%d %d", &n, &q) == 2) { Init(); // debug(); while(q --) { scanf("%s", op); if(op[0] == 'Q') { scanf("%d %d %d", &L, &R, &bx); ans = Get_Ans(L, R, bx); printf("%d\n", ans ? ans : -1); } else if(op[0] == 'I') { scanf("%d %d %d", &px, &ax, &bx); Insert(px, ax, bx); } else if(op[0] == 'D') { scanf("%d", &px); Delete(px); } else if(op[0] == 'R') { scanf("%d", &px); Update_R(px); } else if(op[0] == 'M') { scanf("%d %d", &px, &ax); Update_M(px, ax); } } }#ifdef ___LOCAL_WONZY___ cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;#endif // ___LOCAL_WONZY___ return 0;}
1 0
- zoj 3765 Lights splay
- ZOJ 3765 Lights (SPLAY)
- [ZOJ 3765 Lights] Splay
- zoj 3765 Lights(Splay)
- ZOJ 3765 Lights (SPLAY)
- 【splay tree】 ZOJ 3765 Lights
- ZOJ-3765 Lights(Splay树)
- ZOJ 3765 Lights Splay Tree的几种基本操作
- ZOJ Monthly, March 2014,3765 Lights (Splay 基本操作,并维护区间上的信息 * 模板)
- ZOJ 3765 Lights
- ZOJ 3765 Lights(SplayTree)
- zoj 3765 Lights(伸展树)
- ZOJ 3765 Lights (伸展树)
- ZOJ--3765--Lights【伸展树】
- ZOJ 3765 splay
- zoj3765 Lights ----splay
- ZOJ 3765 —— Lights(伸展树)
- ZOJ 1354 Extended Lights Out
- 计算机网络体系结构及各数据报文结构
- 基于kaldi的在线中文识别,online的操作介绍
- 抛弃隐晦,明了的理解Spring IOC与AOP
- COGS 439 [网络流24题] 软件补丁
- WEB 容器、WEB服务和应用服务器的区别与联系
- [ZOJ 3765 Lights] Splay
- Watson Explorer 入门(2):创建集合(Collection)
- 联想thinkpad E470无线网络无法使用问题解决方法
- 在Docker容器中进行Flask应用的开发
- JavasScript中基本概念关键字和保留字
- kaldi上第一个免费的中文语音识别例子
- JavaScript 1.7 错误try catch throw
- Kibana的图形化——Tile Map
- Android开源框架Image-Loader1.9.5详解