[BZOJ 3682]Phorni
后缀平衡树的模板题? I'm so weak……
现在觉得替罪羊树比 treap 好写,是不是没救了喵~
#include <cstdio>
#include <cmath>
typedef unsigned long long LL;
const double a=0.55;
const LL inf=1ULL<<;
const int sizeOfString=;
const int sizeOfTree=; inline int getint();
inline char getch();
inline int getstr(char * );
inline void putint(int); int n, q, len, type;
char s[sizeOfString];
int P[sizeOfString];
inline void reverse(); struct node {int p, s; LL tag; node * c[];};
node memory_node[sizeOfString], * port_node=memory_node;
node * root;
node * suf[sizeOfString];
inline node * newnode(int);
inline bool cmp(int, int);
inline bool cmp(node * , node * );
node * flatten(node * , node * );
node * build(node * , int);
void print(node * );
void rebuild(node *& );
void remark(node * , LL, LL);
bool insert(node *& , node * , LL=, LL=inf, int=); struct seg {int p; seg * l, * r;};
seg memory_seg[sizeOfTree], * port_seg=memory_seg;
seg * t;
inline seg * newseg();
inline int min(int, int);
seg * build(int, int);
void update(seg * , int, int, int);
int query(seg * , int, int, int, int); int main()
{
int ans=;
char ch;
int c, x, pos, l, r; n=getint(), q=getint(), len=getint(), type=getint();
getstr(s);
reverse(); root=suf[]=newnode();
root->tag=(+inf)>>;
for (int i=;i<=len;i++)
{
suf[i]=newnode(i);
insert(root, suf[i]);
} for (int i=;i<=n;i++) P[i]=getint(); t=build(, n);
for (int i=;i<=q;i++)
{
ch=getch();
if (ch=='I')
{
c=getint(); if (type) c=c^ans;
s[++len]=c+'a';
suf[len]=newnode(len);
insert(root, suf[len]);
}
if (ch=='C')
{
x=getint(); pos=getint();
P[x]=pos;
update(t, , n, x);
}
if (ch=='Q')
{
l=getint(); r=getint();
ans=query(t, , n, l, r);
putint(ans);
}
} return ;
}
inline int getint()
{
register int num=;
register char ch;
do ch=getchar(); while (ch<'' || ch>'');
do num=num*+ch-'', ch=getchar(); while (ch>='' && ch<='');
return num;
}
inline char getch()
{
register char ch;
do ch=getchar(); while (ch!='I' && ch!='C' && ch!='Q');
return ch;
}
inline int getstr(char * str)
{
register int len=;
register char ch;
do ch=getchar(); while (ch<'a' || ch>'z');
do str[++len]=ch, ch=getchar(); while (ch>='a' && ch<='z');
return len;
}
inline void putint(int num)
{
char stack[];
register int top=;
for ( ;num;num/=) stack[++top]=num%+'';
for ( ;top;top--) putchar(stack[top]);
putchar('\n');
}
inline void reverse()
{
static char t[sizeOfString];
for (int i=;i<=len;i++) t[i]=s[len-i+];
for (int i=;i<=len;i++) s[i]=t[i];
}
inline node * newnode(int p)
{
node * ret=port_node++;
ret->p=p; ret->s=;
ret->tag=0LL;
ret->c[]=NULL; ret->c[]=NULL;
return ret;
}
inline bool cmp(int a, int b)
{
return suf[a]->tag<suf[b]->tag;
}
inline bool cmp(node * a, node * b)
{
return s[a->p]==s[b->p]?cmp(a->p-, b->p-):s[a->p]<s[b->p];
}
node * flatten(node * x, node * y)
{
if (!x) return y;
x->c[]=flatten(x->c[], y);
return flatten(x->c[], x);
}
node * build(node * x, int s)
{
node * y, * z;
if (!s) return x->c[]=NULL, x;
y=build(x, s>>); z=build(y->c[], s--(s>>));
y->c[]=z->c[]; z->c[]=y;
return z;
}
void rebuild(node *& t)
{
static node temp;
node * line;
int n=t->s;
line=flatten(t, &temp);
build(line, n);
t=temp.c[];
}
void remark(node * t, LL l, LL r)
{
LL m=(l+r)>>;
t->tag=m; t->s=;
if (t->c[]) remark(t->c[], l, m), t->s+=t->c[]->s;
if (t->c[]) remark(t->c[], m, r), t->s+=t->c[]->s;
}
bool insert(node *& t, node * x, LL l, LL r, int d)
{
LL m=(l+r)>>;
bool ret=false;
if (!t) x->tag=m, t=x, ret=d>(log(root->s)/log(1.0/a));
else
{
t->s++;
if (cmp(t, x)) ret=insert(t->c[], x, m, r, d+);
else ret=insert(t->c[], x, l, m, d+);
if (ret) if ((t->c[] && t->c[]->s>a*t->s) || (t->c[] && t->c[]->s>a*t->s))
{
rebuild(t);
remark(t, l, r);
ret=false;
}
}
return ret;
}
inline seg * newseg()
{
seg * ret=port_seg++;
ret->l=ret->r=NULL;
return ret;
}
inline int min(int x, int y)
{
if (suf[P[x]]->tag<=suf[P[y]]->tag) return x;
return y;
}
seg * build(int l, int r)
{
seg * t=newseg();
if (l==r) return t->p=l, t;
int m=(l+r)>>;
t->l=build(l, m); t->r=build(m+, r);
t->p=min(t->l->p, t->r->p);
return t;
}
void update(seg * t, int l, int r, int p)
{
if (l==r) return ;
int m=(l+r)>>;
if (p<=m) update(t->l, l, m, p);
else update(t->r, m+, r, p);
t->p=min(t->l->p, t->r->p);
}
int query(seg * t, int l, int r, int ql, int qr)
{
if (l==ql && r==qr) return t->p;
int m=(l+r)>>;
if (qr<=m) return query(t->l, l, m, ql, qr);
else if (ql>=m+) return query(t->r, m+, r, ql, qr);
return min(query(t->l, l, m, ql, m), query(t->r, m+, r, m+, qr));
}
又 RE 又 WA 一时爽
到最后也没有搞清楚 zkw 炸在哪里……
大概是 zkw 查询时并不是顺序的缘故?
[BZOJ 3682]Phorni的更多相关文章
- 【BZOJ 3682】Phorni
题目链接 题目描述 Phorni 是一个音之妖精,喜欢在你的打字机上跳舞. 一天,阳光映射到刚刚淋浴过小雨的城市上时,Phorni 用魔法分裂出了许多个幻影,从 1 到 n 编号. 她的每一个幻影都站 ...
- 3682: Phorni 后缀平衡树 线段树
国际惯例的题面: 考虑如果没有强制在线我们能怎么水掉这个题,先构造出字符串,各种方法求一下后缀数组,然后线段树维护区间rank最小的位置即可.然而他要求强制在线,支持插入后缀,并比较后缀大小(求ran ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
随机推荐
- 开源一个网络图片浏览器HooPhotoBrowser
在公司开发项目中需要弹出展示从网络上下载的图片,并提供滑动展示功能.目前采用同事开发的图片浏览器,后期有时间想优化一下.所以重温了下以前开发的类似微博的项目中的图片浏览器代码,并抽取出来封装成了现在这 ...
- 一个非常有意思的css3属性filter
filter这属性貌似可以是img图片在黑白与彩色间转换 filter:grayscale(1)为黑白色,filter:grayscale(0)位彩色,可以用于hover效果 img:hover{fi ...
- java并发包:线程池 executorservice
1.newCachedThreadPool() -缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中 -缓存型池子通常用于执行一些生存期很短的异步型 ...
- cocos2d-x WebSocket
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术.在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道 ...
- linux下内存泄露检测工具Valgrind介绍
目前在linux开发一个分析实时路况的应用程序,在联合测试中发现程序存在内存泄露的情况. 这下着急了,马上就要上线了,还好发现了一款Valgrind工具,完美的解决了内存泄露的问题. 推荐大家可以使用 ...
- Python学习之运算符
Python运算符 算术运算符 运算符 描述 + 相加 - 相减 * 相乘 / 相除 % 取模 ** 幂 // 整除 比较运算符 运算符 描述 == 等于 != 不等于 <> 不等于 &g ...
- sql 日期格式输出 - 转
SELECT CONVERT(varchar(100), GETDATE(), 0) 05 9 2011 9:12AM SELECT CONVERT(varchar(100), GETDATE(), ...
- 关于break和continue的区别
//break是结束整个循环体,continue是结束单次循环 比方说: while(x++ < 10){ if(x == 3) { break; } printf("%d\r\n&q ...
- 01-04 Json和弹窗
//JSON是一种数据格式//JSON比较像php里面的关联数组,它里面存的内容也是key和value成对存在的 </body><script type="text/jav ...
- What Is Mathematics?
What Is Mathematics? The National Council of Teachers of Mathematics (NCTM), the world's largest org ...