BZOJ-3439 Kpm的MC密码

本题被描述者现在才来做这道题。。。对我就是KPM。。。先Orz云神吧~

把所有字符串反向建立一棵Trie,然后建立DFS序,那么Trie上的每个点的子树就对应着DFS序上的一段数。

然后将每个字符串的标号插入,无修改的话只需要主席树。

#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#define rep(i, l, r) for (int i=l; i<=r; i++)
#define down(i, l, r) for (int i=l; i>=r; i--)
#define clr(x, c) memset(x, c, sizeof(x))
#define t(x) Tree[x]
#define maxn 100009
#define maxl 200009
using namespace std;
inline int read()
{
	int x=0; char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x;
}
struct node{int s; node *l, *r;} *blank=new(node), *Tree[maxl];
struct sr{int a, b;} q[maxn];
int n, z, now, t[maxl][26], l[maxl], r[maxl], w[maxn];
char s[maxl];
inline bool cmp(sr a, sr b){return l[a.a]<l[b.a];}
void Add(int k, int l, int r, node *u, node*&t)
{
	if (t==blank) t=new(node), t->l=t->r=blank, t->s=0;
	t->s=u->s+1;
	if (l==r) return; int mid=(l+r)>>1;
	if (k<=mid) t->r=u->r, Add(k, l, mid, u->l, t->l);
		else t->l=u->l, Add(k, mid+1, r, u->r, t->r);
}
inline int Query(int l, int r, int k)
{
	if (t(r)->s-t(l)->s<k) return -1; k--;
	int L=1, R=n; node *u=t(l), *v=t(r); while (L<R)
	{
		int mid=(L+R)>>1, sum=v->l->s-u->l->s;
		if (sum<=k) L=mid+1, v=v->r, u=u->r, k-=sum;
		else R=mid, v=v->l, u=u->l;
	}
	return L;
}
void dfs(int x){l[x]=++now; rep(i, 0, 25) if (t[x][i]) dfs(t[x][i]); r[x]=now;}
inline void Init()
{
	blank->l=blank->r=blank, blank->s=0; 
	t(0)=new(node), t(0)->l=t(0)->r=blank, t(0)->s=0;
}
int main()
{
	n=read(); Init();
	rep(i, 1, n)
	{
		scanf("%s", s); int len=strlen(s), now=0;
		down(j, len-1, 0)
			t[now][s[j]-'a']==0 ? now=t[now][s[j]-'a']=++z : now=t[now][s[j]-'a'];
		q[i].a=now, q[i].b=i, w[i]=now;
	}
	now=0; dfs(0); sort(q+1, q+1+n, cmp);
	for(int i=1, k=1; k<=z+1; k++)
	{
		node *p=t(k-1); 
		while (l[q[i].a]==k)
			Add(q[i++].b, 1, n, p, t(k)=blank), p=t(k);
		t(k)=p;
	}
	rep(i, 1, n) printf("%d\n", Query(l[w[i]]-1, r[w[i]], read()));
}
posted @ 2015-05-05 16:47  NanoApe  阅读(321)  评论(0编辑  收藏  举报
AmazingCounters.com