zoukankan      html  css  js  c++  java
  • 【LOJ#6036】编码

    题面

    https://loj.ac/problem/6036

    题解

    很抱歉的告诉大家,这道题我思考了很长时间,还是不会。

    $yyb$代码的细节我也没有弄懂。我知道以后的学习中我会遇到很多这样的题,可能学习方式要进行转变了。

    我只能把我看明白的部分讲给大家听。

    首先是暴力,我们只要把$trie$树上具有“祖先-后代”关系的点对找出来,然后在他们之间连边,表示它们不能共存。

    其次是优化,我们利用$trie$树的形态优化建边。

    我们考虑对于每一个点,找到它祖先中所有的点连边(和“向子树内点连边等价”)。

    因为可能$trie$树上的一个位置可能躺着很多点,并且处于复杂度考虑,我们把“真正代表它自己的点”挂在$trie$树中它的位置之下。这样我们连边的时候只需要在$trie$树上找到所有它的祖先的位置,暴力连上去就好了(因为$sum_{i=1}^{n}{s_i} le 500000$),所以复杂度是对的。

    这样做还有一个问题,我们连边不能连到自己的反(这个条件是不确切的,确切的向下看),这样的话我们先建一个假点,如果发现要在它上面连边的时候直接建个新点上去,替换它的位置,再让新点向另一棵树中同一个位置的反,表示自己不能到这个点上,在把另一颗树的相同位置连向旧点,表示旧点的值和新点保持一致。这也是要预先排序的原因。

    upd2019.8.19:明白了,经$zsy$指导,我又找到了另一道题【UOJ#210寻找罪犯】,这两题有一个相似的条件,对于$trie$树上的同一个节点下只有一条命题成立,我们只需要建立一个新点,表示如果任意一个成立了,其他的都是假命题,也就是通过加点表示限制。

    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ri register int
    #define N 3000300
    using namespace std;
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    vector<int> to[N];
    
    inline void add_edge(int u,int v) {
      to[u].push_back(v);
      u^=1; v^=1;
      to[v].push_back(u);
    }
    int dfn[N],low[N],clo,bel[N],cnt;
    stack<int> sta; bool ins[N];
    string s[N];
    
    void tarjan(int x) {
      dfn[x]=low[x]=++clo;
      sta.push(x); ins[x]=1;
      for (ri i=0;i<to[x].size();++i) {
        int y=to[x][i];
        if (dfn[y]) {
          if (ins[y]) low[x]=min(low[x],dfn[y]);
        }
        else {
          tarjan(y);
          low[x]=min(low[x],low[y]);
        }
      }
      if (low[x]==dfn[x]) {
        ++cnt;
        while (1) {
          int t=sta.top(); sta.pop();
          bel[t]=cnt; ins[t]=0;
          if (t==x) break;
        }
      }
    }
    
    int ch[N][2],tot;
    int n,len[N],id[N];
    char ss[N];
    
    void insert(int u,int p) {
      int x=n+1,lst=0;
      for (ri i=0;i<len[u];++i) {
        int c=s[u][i]-'0';
        if (!ch[x][c]) ch[x][c]=++tot;
        lst=x; x=ch[x][c]; add_edge(p,x<<1);
      }
      int y=++tot;
      add_edge(p,y<<1|1); add_edge(y<<1,x<<1);
      ch[lst][s[u][len[u]-1]-'0']=y;
    }
    bool cmp(int a,int b) {return len[a]<len[b];}
    
    int main() {
      n=read();
      for (ri i=1;i<=n;++i) {
        scanf("%s",ss);
        len[i]=strlen(ss);
        id[i]=i;
        for (ri j=0;j<len[i];++j) s[i]+=ss[j];
      }
      sort(id+1,id+n+1,cmp);
      tot=n+1;
      for (ri i=1;i<=n;++i) {
        int u=id[i];
        for (ri j=0;j<len[u];++j) 
        if (s[u][j]=='?') {
          s[u][j]='0'; insert(u,u<<1);
          s[u][j]='1'; insert(u,u<<1|1);
          break;
        }
        else if (j==len[u]-1) {
          insert(u,u<<1);
          add_edge(u<<1|1,u<<1);
        }
      }
      for (ri i=1;i<=(tot<<1|1);++i) 
      if (!dfn[i]) tarjan(i);
      for (ri i=1;i<=tot;++i)
      if (bel[i<<1]==bel[i<<1|1]) {
        puts("NO");
        return 0;
      }
      puts("YES");
      return 0;
    }
  • 相关阅读:
    Can't remove netstandard folder from output path (.net standard)
    website项目的reference问题
    The type exists in both DLLs
    git常用配置
    Map dependencies with code maps
    How to check HTML version of any website
    Bootstrap UI 编辑器
    网上职位要求对照
    Use of implicitly declared global variable
    ResolveUrl in external JavaScript file in asp.net project
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11373870.html
Copyright © 2011-2022 走看看