Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) E. National Property

E. National Property

Problem Statement

    You all know that the Library of Bookland is the largest library in the world. There are dozens of thousands of books in the library.
    Some long and uninteresting story was removed…
    The alphabet of Bookland is so large that its letters are denoted by positive integers. Each letter can be small or large, the large version of a letter x is denoted by x’. BSCII encoding, which is used everywhere in Bookland, is made in that way so that large letters are presented in the order of the numbers they are denoted by, and small letters are presented in the order of the numbers they are denoted by, but all large letters are before all small letters. For example, the following conditions hold: 2 < 3, 2’ < 3’, 3’ < 2.
    A word x1 ,  x2 , …,  xa is not lexicographically greater than y1 ,  y2 , …,  yb if one of the two following conditions holds:
    a ≤ b and x1  =  y1 , …,  xa  =  ya , i.e. the first word is the prefix of the second word;
    there is a position 1 ≤ j ≤ min(a, b), such that x1  =  y1 , …,  xj1  =  yj1 and xj  <  yj , i.e. at the first position where the words differ the first word has a smaller letter than the second word has.
    For example, the word “3’7 5” is before the word “2 4’ 6” in lexicographical order. It is said that sequence of words is in lexicographical order if each word is not lexicographically greater than the next word in the sequence.
    Denis has a sequence of words consisting of small letters only. He wants to change some letters to large (let’s call this process a capitalization) in such a way that the sequence of words is in lexicographical order. However, he soon realized that for some reason he can’t change a single letter in a single word. He only can choose a letter and change all of its occurrences in all words to large letters. He can perform this operation any number of times with arbitrary letters of Bookland’s alphabet.
    Help Denis to choose which letters he needs to capitalize (make large) in order to make the sequence of words lexicographically ordered, or determine that it is impossible.
    Note that some words can be equal.

Input

    The first line contains two integers n and m (2 ≤ n ≤ 100 000, 1 ≤ m ≤ 100 000) — the number of words and the number of letters in Bookland’s alphabet, respectively. The letters of Bookland’s alphabet are denoted by integers from 1 to m.
    Each of the next n lines contains a description of one word in format li ,  si,1 ,  si,2 , …,  si,li (1 ≤  li  ≤ 100 000, 1 ≤  si,j  ≤ m), where li is the length of the word, and si,j is the sequence of letters in the word. The words are given in the order Denis has them in the sequence.
    It is guaranteed that the total length of all words is not greater than 100 000.

Output

    In the first line print “Yes” (without quotes), if it is possible to capitalize some set of letters in such a way that the sequence of words becomes lexicographically ordered. Otherwise, print “No” (without quotes).
    If the required is possible, in the second line print k — the number of letters Denis has to capitalize (make large), and in the third line print k distinct integers — these letters. Note that you don’t need to minimize the value k.
    You can print the letters in any order. If there are multiple answers, print any of them.

Examples

Example 1
    Input
        4 3
        1 2
        1 1
        3 1 3 2
        2 1 1
    Output
        Yes
        2
        2 3
Example 2
    Input
        6 5
        2 1 2
        2 1 2
        3 1 2 3
        2 1 5
        2 4 4
        2 4 4
    Output
        Yes
        0
Example 3
    Input
        4 3
        4 3 2 2 1
        3 1 1 3
        3 2 2 3
        2 3 1
    Output
        No

Note

    In the first example after Denis makes letters 2 and 3 large, the sequence looks like the following:

2’
1
1 3’ 2’
1 1

    The condition 2’ < 1 holds, so the first word is not lexicographically larger than the second word. The second word is the prefix of the third word, so the are in lexicographical order. As the first letters of the third and the fourth words are the same, and 3’ < 1, then the third word is not lexicographically larger than the fourth word.
    In the second example the words are in lexicographical order from the beginning, so Denis can do nothing.
    In the third example there is no set of letters such that if Denis capitalizes them, the sequence becomes lexicographically ordered.

题意

    给你一堆由数字组成的串,他们原来不加任何操作的数字大小顺序是1<2<3<4…而你有一个操作,可以将一些数字加一个’(为了方便就叫他大写操作,而原数字就是小写),这样他就比所有小写的数字都要小,并且1’<2’<3’<4’…<1<2<3<4…而且一种数字要大写的话必须所有串中的这个数字都要大写,给出你n个串,问你能否改变一些数字使这些串在字典序上变成不下降的排序。

思路

    虽然很显然这题很容易就想到2-sat的解法,但是有一种不显然但是写起来比2-sat好写到不知道哪里去的方法:
    首先建一个超级源点和一个超级汇点,对于每一个读进来的串,与上一个串作比较,找到第一个不相同的位置,如果该串比上一个串短并且这个串为上一个串的前缀,那么一定是No。
    之后找到这两个串第一个不同的地方,如果这个串的该位数字大于上一个串,那么将这个串的数字向上一个串的该位数字连一条边,表示这两个数字的大小写必须相同;否则如果上一个串的该位数字大于现在这个串的该位数字,将源点s向上一个串的这位数字连一条边,表示这是一个必须大写的数字,再将这个串的该位数字向汇点t连一条边,表示必须小写的数字。
    最后从源点s进行一遍dfs,将遍历到的点都放入数组表示必须改为大写的数字。如果从源点s可以走到汇点t,那么表示是矛盾的,因为与s连边的数字都是必须大写的,而与t连边的数字都是必须小写的数字,两个数字之间的连边表示这两个数字的大小写是一样的。所以如果能从s走到t那么肯定是有矛盾存在的,否则输出存下来的数字就行了。

Code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline void readInt(int &x) {
    x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    x*=f;
}
inline void readLong(ll &x) {
    x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    x*=f;
}
/*================Header Template==============*/
const int maxn=200010;
vector<int> G[maxn];
int a[maxn],b[maxn],len[2],cnt,ans[maxn],n,m,s,t;
bool flg=1,vis[maxn];
inline void dfs(int x) {
    ans[++cnt]=x;vis[x]=1;
    if(x==t)flg=0;
    for(unsigned i=0;i<G[x].size();i++)
        if(!vis[G[x][i]])
            dfs(G[x][i]);
}
int main() {
    readInt(n);
    readInt(m);
    s=m+1;
    t=m+2;
    for(int Case=1;Case<=n;Case++) {
        readInt(len[1]);
        if(Case==1)
            len[0]=len[1]; 
        for(int i=1;i<=len[1];i++) {
            scanf("%d",&b[i]);
            if(Case==1)
                a[i]=b[i];
        }
        int pos=1;
        while(pos<=len[1]&&a[pos]==b[pos])
            pos++;
        if(pos<=len[0]&&pos>len[1])
            return 0*puts("No");
        if(pos<=len[0]&&pos<=len[1]){
            if(a[pos]>b[pos]) {
                G[s].push_back(a[pos]);
                G[b[pos]].push_back(t);
            }
            else
                G[b[pos]].push_back(a[pos]);
        }
        len[0]=len[1];
        for(int i=1;i<=len[1];i++)
            a[i]=b[i];
    }
    dfs(s);
    if(!flg)
        return 0*puts("No");
    puts("Yes");
    printf("%d\n",cnt-1);
        for(int i=2;i<=cnt;i++)
            printf("%d%c",ans[i],i==cnt?'\n':' ');
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值