BZOJ3998: [TJOI2015]弦论
2016-02-26 21:22
417 查看
一开始想构造后缀树来着后来发现就是SAM上面跑一下就好了
时间感人QAQ
时间感人QAQ
#include<cstdio> #include<iostream> #include<cstring> using namespace std; char c; inline void read(int &a) { a=0;do c=getchar();while(c<'0'||c>'9'); while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar(); } struct Node { Node *last,*ch[30]; bool end; int len,time,cur; int ans0,ans2; Node(){last=NULL;for(len=0;len<=29;len++)ch[len]=NULL;len=0;time=1;ans2=0;} }*root,*last; Node *Stack[1000001]; int tot; inline void add(int data,int place) { Node *tp,*ne=new Node; Stack[++tot]=ne; ne->time=1; ne->end=true; ne->len=last->len+1; ne->cur=place; for(tp=last;tp&&!tp->ch[data];tp=tp->last)tp->ch[data]=ne; if(!tp) {ne->last=root,last=ne;return;} else if(tp->len==tp->ch[data]->len-1) {ne->last=tp->ch[data];last=ne;return;} else { Node *a=new Node,*b=tp->ch[data]; *a=*b; a->len=tp->len+1; a->cur=-1; Stack[++tot]=a; a->end=true; a->time=0; b->last=ne->last=a; for(tp;tp&&tp->ch[data]==b;tp=tp->last) tp->ch[data]=a; last=ne; } } int h[600001]; int maxn=600000; Node *S[1000001]; inline void Begin() { for(int i=1;i<=tot;i++) S[i]=Stack[i],h[Stack[i]->len]++; for(int i=1;i<=maxn;i++) h[i]+=h[i-1]; for(int i=1;i<=tot;i++) Stack[h[S[i]->len]--]=S[i]; while(tot) { if(Stack[tot]->last) Stack[tot]->last->time+=Stack[tot]->time; Stack[tot]->ans0=Stack[tot]->end?1:0; Stack[tot]->ans2=Stack[tot]==root?0:Stack[tot]->time; for(int i=0;i<=29;i++) if(Stack[tot]->ch[i]) Stack[tot]->ans0+=Stack[tot]->ch[i]->ans0, Stack[tot]->ans2+=Stack[tot]->ch[i]->ans2; tot--; } } inline void Ans0(Node *Cur,int k) { if(Cur!=root&&k<=1)return; else if(k>Cur->ans0) {puts("-1");return ;} else { if(Cur!=root)k--; for(int i=0;i<=29;i++) if(Cur->ch[i]) if(k>Cur->ch[i]->ans0) k-=Cur->ch[i]->ans0; else {printf("%c",'a'+i),Ans0(Cur->ch[i],k);return;} } } inline void Ans1(Node *Cur,int k) { if(Cur!=root&&k<=Cur->time)return; else if(k>Cur->ans2) {puts("-1");return ;} else { if(Cur!=root)k-=Cur->time; for(int i=0;i<=29;i++) if(Cur->ch[i]) if(k>Cur->ch[i]->ans2) k-=Cur->ch[i]->ans2; else {printf("%c",'a'+i),Ans1(Cur->ch[i],k);return;} } } char ch[600001]; int main() { scanf("%s",ch); int n=strlen(ch); int T,K; root=last=new Node; Stack[++tot]=root; root->end=false; for(int i=1;i<=n;i++) add(ch[i-1]-'a',i); Begin(); scanf("%d%d",&T,&K); T?Ans1(root,K):Ans0(root,K); return 0; }
相关文章推荐
- vim 解决中文乱码,设置高亮,共享粘贴板
- 160227、javascript特效
- 关于子网掩码(Netmask)
- iOS-OC-基本控件之UIPageControl
- UIDatePicker
- processing 鼠标光标显隐设置
- 求n的阶乘后导0的个数
- PCA 和 SVD
- Web前端环境搭建篇之-- 利用NodeJS来安装Ionic和Cordova
- 0819-TableView(tableVeiw控件的代理)(tableView单组 lol数据展示)(tableView-汽车品牌logo 右侧a-z)(KVC)(tableView - 添加删除按钮出现)(自定义代理delegate)(内存)
- php laravel mysql无法连接处理方案(linux服务器配置)
- hdu1160 FatMouse's Speed(LIS普通法)
- PHP常见面试题(简答部分一)
- mysql root密码丢失
- 一些关于树莓派的教程整理
- 使用gprof对应用程序做性能评测
- mysql慢查询日志
- 高版本myeclipse破解以及优化
- 160226、js常用的验证
- 黑马程序员-OC加强-Block