Codeforces Round #376 (Div. 2) D 模拟+线段树区间维护

来源:互联网 发布:大烟雾做丝数据 编辑:程序博客网 时间:2024/05/16 13:00

题目传送门: http://codeforces.com/contest/731/problem/D


题意: 给n个数串,每个串中元素的最大值为c,现在可以进行如下操作:将所有串的所有元素都加一个数k(0<=k<c-1),使得每个数串都是按照字典序排列的


思路: 只要保证每两个串都符合字典序,则所有串都是有序的。然后每两个串的k都有一个区间,最后取所有k的范围的并集,k的范围可以用线段树来储存


代码如下:


#include <iostream>#include <algorithm>#include <cstring>#include <stdio.h>#include <string>#include <cmath>#include <queue>#include <set>#include <map>#include <vector>using namespace std;#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   ll            long long#define   ull           unsigned long long#define   mem(n,v)      memset(n,v,sizeof(n))#define   MAX           2000005#define   MAXN          2000005#define   PI            3.1415926#define   E             2.718281828459#define   opnin         freopen("text.in.txt","r",stdin)#define   opnout        freopen("text.out.txt","w",stdout)#define   clsin         fclose(stdin)#define   clsout        fclose(stdout)#define   haha1         cout << "haha1"<< endl#define   haha2         cout << "haha2"<< endl#define   haha3         cout << "haha3"<< endlconst int    INF    =   0x3f3f3f3f;const ll     INFF   =   0x3f3f3f3f3f3f3f3f;const double pi     =   3.141592653589793;const double inf    =   1e18;const double eps    =   1e-8;const ll     mod    =   1e9+7;const ull    mx     =   133333331;int ans = -1;int vis[MAXN<<2];struct SegTree{    bool flag = false;    void build(int l,int r,int rt){        if(l==r){            vis[rt]=1;            return;        }        int m=(l+r)>>1;        build(lson);        build(rson);        vis[rt]=1;    }    void update(int L,int R,int l,int r,int rt){        if(L > R)        return;        if(L<=l && r<=R){//            cout << "rt,l,r " << rt << ' ' << l << ' ' << r << endl;            vis[rt] = 0;            return;        }        int m=(l+r)>>1;        if(L<=m) update(L,R,lson);        if(m<R) update(L,R,rson);    }    void query(int L,int R,int l,int r,int rt){        if(!vis[rt]) return;        if(l == r){            if(!flag){                ans = l;                flag = true;            }        }        int m=(l+r)>>1;        if(L<=m) query(L,R,lson);        if(m<R) query(L,R,rson);    }}tree;vector<int>a[MAX];int main(){    int n,c;    cin >> n >> c;    for(int i=0;i<n;i++) a[i].clear();    int max_len = 0;    for(int i=0;i<n;i++){        int m;        scanf("%d",&m);        int x;        for(int j=1;j<=m;j++){            scanf("%d",&x);            a[i].push_back(x);        }    }    tree.build(1,c,1);//    haha1;    for(int i=1;i<n;i++){        if(a[i] != a[i-1]){            int min_len = 0;            min_len = min(a[i].size(),a[i-1].size());            int j;            for(j=0;j<min_len;j++){                if(a[i][j] < a[i-1][j]){//                    cout << "<" << endl;//                    cout << "1 " <<  c-a[i-1][j] << endl;                    tree.update(1,c-a[i-1][j],1,c,1);//                    cout << c-a[i][j]+1 << ' ' << c << endl;                    tree.update(c-a[i][j]+1,c,1,c,1);                    break;                }                else if(a[i][j] > a[i-1][j]){//                    cout << ">" << endl;//                    cout << c-a[i][j]+1 <<  ' ' << c-a[i-1][j] <<endl;                    tree.update(c-a[i][j]+1,c-a[i-1][j],1,c,1);                    break;                }            }            if(j == min_len && a[i] < a[i-1]){                cout << "-1" << endl;                return 0;            }        }    }//    for(int i=1;i<=c*2;i++) cout << vis[i] << ' ';//    cout << endl;    tree.query(1,c,1,c,1);    if(ans >= 0){        if(ans == c) cout << "0" << endl;        else cout << ans << endl;;    }    else cout << "-1" <<endl;    return 0;}
0 0
原创粉丝点击