zoukankan      html  css  js  c++  java
  • 6.14考试

    T1 Censoring

    题意:给定n个模式串,在母串S中不断删除n词,输出最后S。先删最早,n词中无子串。

    题意眼熟,连题名也眼熟。之前做过的是kmp,无非改到了Trie上AC自动机解决。

    建Trie给每个词打标记记录长度,建AC自动机别忘考虑后缀上的标记(abcaca  ca),然后跑母串,栈存字符,指针数组存匹配位置,若有标记退栈len...

    40min敲完

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define MAXN 100005
    #define reg register
    #define F(i,a,b) for(i=a;i<=b;++i)
    using namespace std;
    char s[MAXN],w[MAXN],ls;
    struct Trie{
        Trie *son[26],*fail;
        bool ed;
        int len;
    };
    int top;
    char stack[MAXN];
    Trie *mc[MAXN];
    queue<Trie*> q;
    Trie *newnode()
    {
        Trie *p=new Trie;
        p->fail=NULL;
        reg int i;
        F(i,0,25) p->son[i]=NULL;
        p->ed=0;
        p->len=-1;
        return p;
    }
    void in(Trie *root)
    {
        reg int i=0,c; Trie *p=root;
        while(w[++i])
        {
            c=w[i]-'a';
            if(p->son[c]==NULL) p->son[c]=newnode();
            p=p->son[c];
        }
        p->ed=1;
        p->len=strlen(w+1);
    }
    void AC(Trie *root)
    {
        Trie *p=root;
        reg int i;
        F(i,0,25)
        {
            if(root->son[i]!=NULL)
            {
                root->son[i]->fail=root;
                q.push(root->son[i]);
            }
            else root->son[i]=root;
        }
        while(!q.empty())
        {
            p=q.front();
            q.pop();
            F(i,0,25)
            {
                if(p->son[i]!=NULL)
                {
                    p->son[i]->fail=p->fail->son[i];
                    q.push(p->son[i]);
                }
                else p->son[i]=p->fail->son[i];
                if(p->son[i]->fail!=NULL)
                {
                    p->son[i]->ed=max(p->son[i]->ed,p->son[i]->fail->ed);
                    p->son[i]->len=max(p->son[i]->len,p->son[i]->fail->len);            //!!!!
                }
            
            }
        }
    }
    void ask(Trie *root)
    {
        Trie *p=root; reg int i=0,c,j;                //i=0 eee
        while(s[++i])
        {
            if(p==NULL) p=root;
            c=s[i]-'a';
            p=p->son[c];
            stack[++top]=s[i];
            mc[top]=p;
            if(p->ed==1)            //不能清零 
            {
    //            printf("%d
    ",i);
                top-=p->len;
                p=mc[top];
    //            F(j,1,top) printf("%c",stack[j]); puts("");
            }
        }
    }
    int main()
    {
    //    freopen("cen.in","r",stdin);
    //    freopen("cen.out","w",stdout);
        scanf("%s",s+1);
        ls=strlen(s+1);
        int n; reg int i;
        scanf("%d",&n);
        Trie *root=newnode();
        F(i,1,n)
        {
            scanf("%s",w+1);
            in(root);
        }
        AC(root);
        ask(root);
        F(i,1,top) printf("%c",stack[i]);
    //    fclose(stdin);
    //    fclose(stdout);
        return 0;
    }
    View Code

    T2 bzoj4899

    期望送命题,而且还没给数据范围...

    https://blog.csdn.net/WerKeyTom_FTD/article/details/53026266

    省时间放直链

    T3 雨天的尾巴

    题意:n点树,m次将x-y路径赋z,求最后1~n点各自的最大次数z。

    一开始想的带修主席树额,虽然考试时算了下爆空间,但还是打了然后并调不对。

    错因:dfs序+差分nc想错了。

    正确姿势:树上差分+线段树合并

    树上差分:x+1,y+1,lca-1,f(lca)-1 统计子树即实际。

    对每个点建权值线段树(动态开点空间O(4mlogn),不然4n^2爆炸),维护权值的最大出现次数和值以便O(1)查。最后dfs回溯合并查值即可。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue> 
    #include<algorithm>
    #define MAXN 100005
    #define awsl 50
    #define reg register
    #define F(i,a,b) for(i=a;i<=b;++i)
    using namespace std;
    queue<int> q;
    struct R{
        int u,v,next;
    }r[2*MAXN];
    struct ASK{
        int x,y,z;
    }ask[MAXN];
    int fir[MAXN],lc[awsl*MAXN],rc[awsl*MAXN],tot,siz[awsl*MAXN],ans[MAXN],num[awsl*MAXN],lsh[MAXN],cnt,root[MAXN],f[MAXN][25],dep[MAXN],mdp,o=1,n,m;
    int read()                    //o=1         eeeee
    {
        reg char c; reg int x=0;                    //x=0            eeeeeeee
        c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9')
        {
            x=x*10+c-48;
            c=getchar();
        }
        return x;
    }
    void add(int u,int v)
    {
        r[o].u=u;
        r[o].v=v;
        r[o].next=fir[u];
        fir[u]=o++;
    }
    void dfs(int u,int d)
    {
    //    printf("u=%d %d
    ",u,d);
        dep[u]=d;
        reg int i,v,j;
        for(i=fir[u];i;i=r[i].next)
        {
            v=r[i].v;
            if(v==f[u][0]) continue;
            f[v][0]=u;
    //        printf("%d %d
    ",u,v);
            F(j,1,mdp)
                f[v][j]=f[f[v][j-1]][j-1];
            dfs(v,d+1);
        }
    }
    void bfs(int st)
    {
        reg int i,j,u,v;
        dep[st]=1;
        q.push(st);
        while(!q.empty())
        {
            u=q.front();
            q.pop();
            for(i=fir[u];i;i=r[i].next)
            {
                v=r[i].v;
                if(dep[v]) continue;
                dep[v]=dep[u]+1;
                f[v][0]=u;
                F(j,1,mdp)
                    f[v][j]=f[f[v][j-1]][j-1];
                q.push(v);
            }
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]>dep[y]) x^=y^=x^=y;
    //    printf("wee%d
    ",x);
        reg int i;
        for(i=mdp;i>=0;--i)
            if(dep[f[y][i]]>=dep[x])
                y=f[y][i];
        if(x==y) return x;
    //    if(f[x][0]==f[y][0]) return f[x][0];
        for(i=mdp;i>=0;--i)
            if(f[x][i]!=f[y][i])
            {
                x=f[x][i];
                y=f[y][i];
            }
        return f[x][0];
    }
    void up(int k)
    {
    //    printf("%d %d
    ",siz[lc[k]],siz[rc[k]]);
        if(siz[lc[k]]>=siz[rc[k]])
            siz[k]=siz[lc[k]],num[k]=num[lc[k]];
        else
            siz[k]=siz[rc[k]],num[k]=num[rc[k]];
    }
    void ch(int &k,int l,int r,int x,int c)
    {
        if(!k) k=++tot;
        if(l==r)
        {
            siz[k]+=c;
            num[k]=l;
            return;
        }
        int mid=(l+r)>>1;
        if(x<=mid) ch(lc[k],l,mid,x,c);
        else ch(rc[k],mid+1,r,x,c);
        up(k);
    }
    int merge(int x,int y,int l,int r)
    {
        if(!x||!y) return x+y;
        if(l==r)
        {
            siz[x]+=siz[y];
            num[x]=l;
            return x;
        }
        int mid=(l+r)>>1;
        lc[x]=merge(lc[x],lc[y],l,mid);
        rc[x]=merge(rc[x],rc[y],mid+1,r);
    //    printf("%d %d %d
    ",siz[x],siz[lc[x]],siz[rc[x]]);
        up(x);
        return x;
    }
    void dfs2(int u)
    {
        reg int i,v;
    //    printf("u=%d
    ",u);
        for(i=fir[u];i;i=r[i].next)
        {
            v=r[i].v;
            if(v==f[u][0]) continue;
            dfs2(v);
    //        printf("root %d
    ",root[v]);
            if(root[v]) root[u]=merge(root[u],root[v],1,cnt);
        }
    //    printf("%d %d
    ",u,num[root[u]]);
        ans[u]=siz[root[u]]?lsh[num[root[u]]]:0;
    }
    int main()
    {
    //    freopen("17.in","r",stdin);
        n=read(); m=read(); mdp=(int)log2(n)+1;
        reg int i,a,b,c;
        F(i,1,n-1)
        {
            a=read(); b=read();
            add(a,b); add(b,a);
        }
        dfs(1,1);
    //    dep[0]=-1;
    //    bfs(1);
        F(i,1,m) ask[i].x=read(),ask[i].y=read(),ask[i].z=lsh[i]=read();//,printf("!!!  %d
    ",ask[i].z);
        sort(lsh+1,lsh+m+1);
        cnt=unique(lsh+1,lsh+m+1)-lsh-1;
        F(i,1,m) ask[i].z=lower_bound(lsh+1,lsh+cnt+1,ask[i].z)-lsh;
        reg int g;
        F(i,1,m)
        {
            ch(root[ask[i].x],1,cnt,ask[i].z,1);
            ch(root[ask[i].y],1,cnt,ask[i].z,1);
            g=lca(ask[i].x,ask[i].y);
            ch(root[g],1,cnt,ask[i].z,-1);
            if(f[g][0]) ch(root[f[g][0]],1,cnt,ask[i].z,-1);
        }
        dfs2(1);
        F(i,1,n) printf("%d
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    MTK Android 源码目录分析
    MTK Android 平台语言支持状态
    开坑了啦啦啦..
    codeforces泛做..
    用介个新的blog咯..
    【UR #5】怎样跑得更快
    【UR #5】怎样提高智商
    【集训队互测2016】消失的源代码
    口胡
    [八省联考2018]劈配
  • 原文地址:https://www.cnblogs.com/hzoi-yzh/p/11043949.html
Copyright © 2011-2022 走看看