zoukankan      html  css  js  c++  java
  • CF 1023D Array Restoration

    题解

    非常容易想到的线段树, 还可以用并查集来。 还有一位大神用了$O(n)$ 就过了Orz

    要判断是否能染色出输入给出的序列,必须满足两个条件:

    1、 序列中必须存在一个$q$

    2、 两个相同的数$x$的中间不存在比 $ x$ 小的数

    首先判断输入的数列中是否存在$q$, 若不存在$q$ 且没有 $a_i = 0$, 表示序列中一定没有$q$, 直接输出NO

      若存在某个$a_i = 0$ , 将任意一个染成$q$即可

    然后我们再查询两个相同的数$x$ 中是否存在比$x$ 小的数,用线段树来维护区间最小即可实现

      接着把两个$x$中间的序列染色, 用MinOK来记录,表示区间内$a_i = 0$,可以染色的最小值。 (线段树区间修改

      最后把$a_i = 0$ 进行染色(利用线段树点查询

    CF现场就想到的算法,然而没有特判存在$q$,pushdown还少打了唔, CF百分百掉分,我要变成pupil了,太惨啦QAQ

    代码

      1 #include<cstring>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #define lson nd<<1
      5 #define rson nd<<1|1
      6 #define rd read()
      7 #define rep(i,a,b) for(int i = (a); i <= (b); ++i)
      8 #define per(i,a,b) for(int i = (a); i >= (b); --i)
      9 using namespace std;
     10 
     11 const int N = 3e5, inf = ~0U >> 2;
     12 
     13 int MIN[N << 2], a[N], L[N], R[N], lazy[N << 2], q, n, pos;
     14 int Mok[N << 2];
     15 
     16 int read() {
     17     int X = 0, p = 1; char c = getchar();
     18     for(; c > '9' || c < '0'; c = getchar()) if( c == '-') p = -1;
     19     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
     20     return X * p;
     21 }
     22 
     23 void update(int nd) {
     24     MIN[nd] = min(MIN[lson], MIN[rson]);
     25 }
     26 
     27 void pushdown(int nd) {
     28     if(lazy[nd]) {
     29         Mok[lson] = lazy[nd];
     30         Mok[rson] = lazy[nd];
     31         lazy[lson] = lazy[rson] = lazy[nd];
     32         lazy[nd] = 0;
     33     }
     34 }
     35 
     36 void build(int l, int r, int nd) {
     37     if(l == r) {
     38         MIN[nd] = a[l] == 0 ? inf : a[l];
     39         return;
     40     }
     41     int mid = (l + r) >> 1;
     42     build(l, mid, lson);
     43     build(mid + 1, r, rson);
     44     update(nd);
     45 }
     46 
     47 int query(int Li, int Ri, int l, int r, int nd) {//查询区间最小
     48     if(Li <= l && r <= Ri) return MIN[nd];
     49     int mid = (l + r) >> 1, re = inf;
     50     if(Li <= mid) re = min(re, query(Li, Ri, l, mid, lson));
     51     if(mid < Ri) re = min(re, query(Li, Ri, mid + 1, r, rson));
     52     return re;
     53 }
     54 
     55 int query_pt(int p, int l, int r, int nd) {//查询可以染上的值
     56     if(l == r) return Mok[nd];
     57     int mid = (l + r) >> 1;
     58     pushdown(nd);
     59     if(p <= mid) return query_pt(p, l, mid, lson);
     60     else return query_pt(p, mid + 1, r, rson);
     61 }
     62 
     63 void change(int Li, int Ri, int c, int l, int r, int nd) {
     64     if(Li <= l && r <= Ri) {
     65         lazy[nd] = c;
     66         Mok[nd] = c;
     67         return;
     68     }
     69     int mid = (l + r) >> 1;
     70     pushdown(nd);
     71     if(Li <= mid) change(Li, Ri, c, l, mid, lson);
     72     if(mid < Ri) change(Li, Ri, c, mid + 1, r, rson);
     73     update(nd);    
     74 }
     75 
     76 int main()
     77 {
     78     n = rd; q = rd;
     79     for(int i = 1; i <= n; ++i) {
     80         a[i] = rd;
     81         if(!a[i]) pos = i;
     82         if(!L[a[i]]) L[a[i]] = i;
     83         R[a[i]] = i;
     84     }
     85     if(!L[q] && !pos) return printf("NO
    "), 0;//无a[i]=0也无q
     86     build(1, n, 1);
     87     for(int i = 1; i <= q; ++i) {//必须按颜色从小到大覆盖
     88         if(!L[i]) continue;
     89         int minv = query(L[i], R[i], 1, n, 1);
     90         if(minv < i) return printf("NO
    "), 0;
     91         change(L[i], R[i], i, 1, n, 1);
     92     }
     93     for(int i = 1; i <= n; ++i) if(!a[i]) {
     94         a[i] = query_pt(i, 1, n, 1);
     95         if(i == pos && !L[q]) a[i] = q; // 必须存在q
     96         else if(!a[i]) a[i] = 1;
     97     }
     98     printf("YES
    ");
     99     for(int i = 1; i <= n; ++i) printf("%d ", a[i]);
    100     putchar('
    ');
    101 }
    View Code

     

  • 相关阅读:
    Neditor 2.1.16 发布,修复缩放图片问题
    Neditor 2.1.16 发布,修复缩放图片问题
    每日 30 秒 ⏱ 强风吹拂
    每日 30 秒 ⏱ 强风吹拂
    Python3的日期和时间
    内置函数:exec、eval、compile
    内置函数:zip、filter、map、stored
    匿名函数
    列表推导式和生成器表达式
    生成器send的用法案例
  • 原文地址:https://www.cnblogs.com/cychester/p/9502367.html
Copyright © 2011-2022 走看看