分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

【JSOI2008】最大数

发布时间:2023-09-06 01:14责任编辑:彭小芳关键词:暂无标签

https://www.luogu.org/problem/show?pid=1198

之前刚学完Splay想找题练手的时候做的,写完Splay交上去了才发现这应该是线段树裸题23333

Splay解法

按照要求操作即可……

#include <iostream>using namespace std;int m, d, t;const int inf = 0x7fffffff;namespace splay{struct node;node *nil = 0, *root;struct node{ ???int val, size, maxnum; ???node *ch[2]; ???node(int v) : val(v), size(1), maxnum(v) ???{ ???????ch[0] = ch[1] = nil; ???} ???void pull_up() ???{ ???????size = ch[0]->size + ch[1]->size + 1; ???????maxnum = max(val, max(ch[0]->maxnum, ch[1]->maxnum)); ???} ???int cmp(int k) ???{ ???????if(this == nil || k == ch[0]->size + 1) ???????????return -1; ???????else ???????????return (k <= ch[0]->size) ? 0 : 1; ???}};void init(){ ???if(!nil) ???????nil = new node(-inf); ???nil->size = 0; ???nil->ch[0] = nil->ch[1] = nil; ???root = new node(-inf); ???root->ch[1] = new node(-inf); ???root->size = 2;}void rotate(node *&t, int d){ ???node *k = t->ch[d ^ 1]; ???t->ch[d ^ 1] = k->ch[d]; ???k->ch[d] = t; ???t->pull_up(); ???k->pull_up(); ???t = k;}void splay(int k, node *&t = root){ ???int d1 = t->cmp(k); ???if(d1 == 1) ???????k = k - t->ch[0]->size - 1; ???if(d1 != -1) ???{ ???????int d2 = t->ch[d1]->cmp(k); ???????if(d2 != -1) ???????{ ???????????int k2 = (d2 == 1) ? (k - t->ch[d1]->ch[0]->size - 1) : k; ???????????splay(k2, t->ch[d1]->ch[d2]); ???????????if(d1 != d2) ???????????{ ???????????????rotate(t->ch[d1], d2 ^ 1); ???????????????rotate(t, d1 ^ 1); ???????????} ???????????else ???????????{ ???????????????rotate(t, d1 ^ 1); ???????????????rotate(t, d2 ^ 1); ???????????} ???????} ???????else ???????????rotate(t, d1 ^ 1); ???}}void insert(int val){ ???splay(root->size - 1); ???node *k = root->ch[1]; ???root->ch[1] = new node(val); ???root->ch[1]->ch[1] = k; ???k->pull_up(); ???root->ch[1]->pull_up(); ???root->pull_up();}int get_maxnum(int len){ ???int from = root->size - len; ???int to = from + len - 1; ???splay(to + 1, root); ???splay(from - 1, root->ch[0]); ???return root->ch[0]->ch[1]->maxnum;}}int main(){ ???using namespace splay; ???cin >> m >> d; ???init(); ???char a; ???int b; ???while(m--) ???{ ???????cin >> a >> b; ???????switch(a) ???????{ ???????case ‘A‘: ???????????insert((b + t) % d); ???????????break; ???????case ‘Q‘: ???????????t = get_maxnum(b); ???????????cout << t << endl; ???????????break; ???????} ???} ???return 0;}

线段树解法

M<=2e5,也就是极限状况下最多2e5个数。开个长度是2e5的线段树,再记录下已经加了N个数了。每次插入就是更改第N+1个元素,查询就是查询区间[N-L+1,N]的最大值。

懒得重写一遍了……

【JSOI2008】最大数

原文地址:http://www.cnblogs.com/ssttkkl/p/7606268.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved