• 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
    ", Query(l[w[i]]-1, r[w[i]], read()));
    }
  • 相关阅读:
    【mysql优化1】表的优化与列类型选择
    mysql 各数据类型的 大小及长度
    android如何建立数据库。(如何重写SQLiteOpenHelper)
    PHP中统计目录中文件以及目录中目录的大小
    如何下载coursera视频
    JAVAEE filter总结
    zookeeper安装
    如何从硬盘安装fedora 19 (How to install fedora 19 from hard drive, Fedora-19-i386-DVD.iso)
    WCF 项目应用连载[3]
    POJ1184-------操作分离的BFS
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4479585.html
Copyright © 2020-2023  润新知