文章目录

  • [JSOI2008]火星人prefix
  • Strange Queries

[JSOI2008]火星人prefix

BZOJ1014
思路很好想,哈希字符串即可

只是平衡树的码量大

注意因为splay加入哨兵的原因,每个点在平衡树内的排名比真实排名大111(有极小值的占位)

考虑的时候就只在询问的时候考虑,修改的时候忘了就挂了

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define maxn 100005
#define ull unsigned long long
struct node {int son[2], f, val, siz;ull hash;
}t[maxn];
int root, n, Q;
ull mi[maxn];
int val[maxn];
char s[maxn];void read( int &x ) {x = 0; char c = getchar();while( c < '0' or c > '9' ) c = getchar();while( '0' <= c and c <= '9' ) { x = ( x << 1 ) + ( x << 3 ) + ( c ^ 48 ); c = getchar(); }
}void pushup( int x ) {if( ! x ) return;t[x].siz = 1;if( t[x].son[0] ) t[x].siz += t[t[x].son[0]].siz;if( t[x].son[1] ) t[x].siz += t[t[x].son[1]].siz;t[x].hash = mi[t[t[x].son[0]].siz] * t[x].val + t[t[x].son[0]].hash + t[t[x].son[1]].hash * mi[t[t[x].son[0]].siz + 1];
}void rotate( int x ) {int fa = t[x].f;int Gfa = t[fa].f;int k = t[fa].son[1] == x;t[Gfa].son[t[Gfa].son[1] == fa] = x;t[x].f = Gfa;t[fa].son[k] = t[x].son[k ^ 1];if( t[x].son[k ^ 1] ) t[t[x].son[k ^ 1]].f = fa;t[x].son[k ^ 1] = fa;t[fa].f = x;pushup( fa );pushup( x );
}void splay( int x, int goal ) {while( t[x].f ^ goal ) {int fa = t[x].f, Gfa = t[fa].f;if( Gfa ^ goal )   ( t[Gfa].son[0] == fa ) ^ ( t[fa].son[0] == x ) ? rotate( x ) : rotate( fa );rotate( x );}if( ! goal ) root = x;
}int build( int now, int l, int r ) {if( l > r ) return 0;int mid = ( l + r ) >> 1;t[mid].hash = val[mid];t[mid].val = val[mid];t[mid].siz = 1;t[mid].f = now;if( l == r ) return l;t[mid].son[0] = build( mid, l, mid - 1 );t[mid].son[1] = build( mid, mid + 1, r );pushup( mid );return mid;
}int find( int x ) {int now = root;while( 1 ) {if( t[t[now].son[0]].siz >= x ) now = t[now].son[0];else if( t[t[now].son[0]].siz + 1 == x ) return now;else x -= t[t[now].son[0]].siz + 1, now = t[now].son[1];}
}int Hash( int x, int y ) {int l = find( x - 1 );int r = find( y + 1 );splay( l, 0 );splay( r, l );return t[t[r].son[0]].hash;
}int main() {mi[0] = 1;for( int i = 1;i < maxn;i ++ ) mi[i] = mi[i - 1] * 27ull;scanf( "%s", s ); read( Q ); val[++ n] = 0;int len = strlen( s );for( int i = 0;i < len;i ++ )val[++ n] = s[i] - 'a' + 1;val[++ n] = 0;root = build( root, 1, n );char opt[5], ch[5]; int x, y;while( Q -- ) {scanf( "%s", opt ); read( x ); x ++;switch( opt[0] ) {case 'Q' : {read( y ); y ++;if( x > y ) swap( x, y );int ans = 0, l = 1, r = n - y;while( l <= r ) {int mid = ( l + r ) >> 1;if( Hash( x, x + mid - 1 ) == Hash( y, y + mid - 1 ) )ans = mid, l = mid + 1;elser = mid - 1;}printf( "%d\n", ans );break;}case 'R' : {scanf( "%s", ch );splay( find( x ), 0 );t[root].val = ch[0] - 'a' + 1;pushup( root );break;}case 'I' : {scanf( "%s", ch );int l = find( x );int r = find( x + 1 );splay( l, 0 );splay( r, l );t[r].son[0] = ++ n;t[n].hash = ch[0] - 'a' + 1;t[n].val = ch[0] - 'a' + 1;t[n].siz = 1;t[n].f = r;splay( n, 0 );break;}}}return 0;
}

Strange Queries

CODECHEF

显然每个点只会与其左右相邻点连边

这种区间内合并的问题,是非常常见的类似线段树维护区间最大子段和的感觉

但是这是动态维护,所以用平衡树就行

具体而言,对于每一段区间

  • 维护区间左端点还没有连线的最小值l_
  • 右端点还没有连线的最小值_r
  • 左右端点都没有连线的最小值l__r
  • 区间每个点都至少有一条连线的最小值ans
  • 维护区间左右端点的权值val_l val_r

考虑两个区间的合并

  • ans

    • 两个区间的答案相加

    • 左区间的右端点和右区间的左端点都没连线,此时在两点之间连线

      花费为右区间左端点的权值与左区间右端点的权值差

  • l_

    • 左区间仍只有左端点没连线l_,右区间均连线ans
    • 左区间两端都没连线l__r,右区间左端点没连线l_,同样两区间可以连线
  • _r

    • 右区间只有右端点没连线_r,左区间均连线ans
    • 右区间两端都没连线l__r,左区间右端点没连线_r,两区间连线
  • l__r

    • 左区间只有左端点没连线l_,右区间只有右端点没连线_r
    • 左区间和右区间两端都没连线l__r,此时左区间右端点和右区间左端点连线

fhq-treap维护即可

#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
#define maxn 200005
#define inf 1e9
struct node {int key, lson, rson, val, val_l, val_r, l_, _r, l__r, ans;node(){}node( int v ) {ans = inf;key = rand();val = val_l = val_r = v;lson = rson = l_ = _r = l__r = 0;}
}t[maxn];
int T, n, Q, root, cnt;
int a[maxn];void pushup( node lst, node nxt, int &ans, int &l_, int &_r, int &l__r ) {if( lst.val_l <= -inf and lst.val_r >= inf ) {ans = nxt.ans;l_ = nxt.l_;_r = nxt._r;l__r = nxt.l__r;return;}if( nxt.val_l <= -inf and nxt.val_r >= inf ) {ans = lst.ans;l_ = lst.l_;_r = lst._r;l__r = lst.l__r;return;}int w = nxt.val_l - lst.val_r;ans = min( lst.ans + nxt.ans, lst._r + nxt.l_ + w );l_ = min( lst.l_ + nxt.ans, lst.l__r + nxt.l_ + w );_r = min( nxt._r + lst.ans, nxt.l__r + lst._r + w );l__r = min( lst.l_ + nxt._r, lst.l__r + nxt.l__r + w );
}void pushup( int x ) {t[x].val_l = t[x].val_r = t[x].val;t[x].l_ = t[x]._r = t[x].l__r = 0;t[x].ans = inf;if( t[x].lson ) {pushup( t[t[x].lson], t[x], t[x].ans, t[x].l_, t[x]._r, t[x].l__r );t[x].val_l = t[t[x].lson].val_l;}if( t[x].rson ) {pushup( t[x], t[t[x].rson], t[x].ans, t[x].l_, t[x]._r, t[x].l__r );t[x].val_r = t[t[x].rson].val_r;}
}void split( int now, int val, int &x, int &y ) {if( ! now ) x = y = 0;else {if( t[now].val <= val ) {x = now;split( t[now].rson, val, t[now].rson, y );pushup( x );}else {y = now;split( t[now].lson, val, x, t[now].lson );pushup( y );}}
}int merge( int x, int y ) {if( ! x or ! y ) return x + y;if( t[x].key < t[y].key ) {t[x].rson = merge( t[x].rson, y );pushup( x );return x;}else {t[y].lson = merge( x, t[y].lson );pushup( y );return y;}
}signed main() {t[0].val_l = -inf, t[0].val_r = inf;scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld", &n, &Q );root = 0;for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i] );sort( a + 1, a + n + 1 );for( int i = 1;i <= n;i ++ ) {t[i] = node( a[i] );root = merge( root, i );}cnt = n;int opt, x, l, r, L, R;while( Q -- ) {scanf( "%lld %lld", &opt, &x );if( opt & 1 ) {split( root, x, l, r );t[++ cnt] = node( x );root = merge( l, merge( cnt, r ) );}else {split( root, x, l, r );split( l, x - 1, L, R );root = merge( L, r );}printf( "%lld\n", t[root].ans >= inf ? 0 : t[root].ans );}}return 0;
}

splay/fhq-treap 问卷调查反馈—— [JSOI2008]火星人prefix(splay),Strange Queries(fhq-treap)相关推荐

  1. bzoj 1014: [JSOI2008]火星人prefix(splay维护区间+Hash+二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7588  Solved: 2429 [Submi ...

  2. BZOJ1014: [JSOI2008]火星人prefix

    BZOJ1014: [JSOI2008]火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀. 比方说,有这样一个字符串:madamimadam,我们将这 ...

  3. BZOJ 1014 [JSOI2008]火星人prefix

    splay维护hash值: 看到大佬们都在打数据结构,我说好的不打数据结构又自己打脸了. 为了写这个昨天还特意去打了Splay的普通平衡树,自从我学会Treap以来第一次用splayA掉普通平衡树QA ...

  4. bzoj 1014 火星人prefix —— splay+hash

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用 splay 维护字符串上不同位置的哈希值还是第一次... 具体就是每个节点作为位置 ...

  5. [BZOJ 1014][JSOI2008]火星人prefix(Splay+二分+hash)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam, 我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...

  6. 【BZOJ1014】【JSOI2008】火星人prefix Splay处理区间,hash+dichotomy(二分)check出解...

    题意不赘述了,太清晰了. 说题解:首先依据原字符串建立SPT.首尾建议多加一个空白字符. 给一个树构图,依照平衡树的前后大小顺序性质能够使它们始终维持为一个序列,而且能够通过rank找到序列的第k个. ...

  7. 【BZOJ1014】【JSOI2008】火星人prefix Splay处理区间,hash+dichotomy(二分)check出解

    题意不赘述了,太清晰了. 说题解:首先根据原字符串建立SPT,首尾建议多加一个空白字符. 给一个树构图,按照平衡树的前后大小顺序性质可以使它们始终维持为一个序列,并且可以通过rank找到序列的第k个. ...

  8. [JSOI2008]火星人 hash+splay

    题目描述: 现在,火星人定义了一个函数 LCQ(x, y)LCQ(x,y),表示:该字符串中第 xx 个字符开始的字串,与该字符串中第 yy 个字符开始的字串,两个字串的公共前缀的长度.比方说,LCQ ...

  9. 【BZOJ1014】【tyvj3486】火星人prefix,Splay+字符串hash

    Time:2016.07.19 Author:xiaoyimi 转载注明出处谢谢 传送门1 传送门2 思路&&注意: LCP这个东西可以用后缀数组,扩展kmp什么的来做 这里加上了插入 ...

最新文章

  1. BASIC-1_蓝桥杯_闰年判断
  2. 题目1208:10进制 VS 2进制(进制转换以及大数保存问题)
  3. 【机器学习】Python 快速入门笔记
  4. 利用ssh反向代理以及autossh实现从外网连接内网服务器
  5. ueditor video 设置宽高的问题(uni app)
  6. Java中多态、抽象类和接口
  7. PHP分页类的实现,返回结果未渲染,更容易在HTML中使用
  8. 实现IMSI、IMEI查询
  9. 【报告分享】2020年中国知识图谱行业研究报告.pdf(附下载链接)
  10. 暗黑启示录bt版java下载,Transmission搭建BT下载服务器
  11. python拦截游戏封包_TCP封包拦截类模块 API HooK封包拦截源码
  12. 在linux上下载图片,在Linux上使用4k Stogram下载Instagram图片库 | MOS86
  13. Unmapped Spring configuration files found. Please configure Spring facet
  14. linux学习资料(转帖收藏)
  15. 未来IT互联网企业的发展前景
  16. ValueError: Variable in_hidden/weights already exists, disallowed. Did you mean to set reuse=True or
  17. oracle.-904,ORACLE 11G ORA-904 while running select query(BUG)
  18. 有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第 3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后 问第一个人,他说是10岁。请问第
  19. 人工智能(Machine Learning)—— 机器学习
  20. go项目部署服务器保姆级教程(带图)

热门文章

  1. 最全知识点总结!| 大数据学习路线指南
  2. C语言关系 是行还是列,C语言行优先和列优先的问题深入分析
  3. 腐蚀rust服务器命令_RUST++ MOD
  4. php 筛选数组,2020-07-24 php 通过数组键值对筛选数组
  5. # 睡眠3秒_【for fun】睡眠排序算法
  6. dev可以运行mysql文件夹_Linux查看mysql 安装路径和运行路径
  7. 后端返回number类型数据_Javascript基础教程之数据类型 (数值 Number)
  8. 游戏设计与计算机,RPG游戏设计与实现-数学与计算机系.doc
  9. 7-42 整型关键字的散列映射 (25 分)(思路加详解)兄弟们 来呀 写题呀
  10. C++文本文件操作和二进制文件读写