zoukankan      html  css  js  c++  java
  • CF1557D Ezzat and Grid

    题意:给你个n行1e9列的01矩阵。i行和i+1行是相邻的当且仅当存在一列,这两行这一列的数都是1。问最少删掉多少行,才能使对于每个1<=i<m,i行和i+1行都相邻。m是删掉之后的总行数。输出方案。

    解:首先发现,两个行能够相邻,一定是通过某个两者都是1的位置联系起来。

    怎么做呢,想了一想想到了连边图论,然后马上发现边数是n²的,那没事了。再进一步,想到了DO。就设f[i]表示选了第i行,前面的全都相邻,要删掉的最少行数。那么转移就是对于这一行每个是1的地方,如果前面某一行这里也是1,那么可以从那一行转移来,转移方程是f[i]=min(f[j]+(i-j-1)),发现这个转移方程可以化成f[i]-i=min(f[j]-j)-1,于是我们考虑维护一个数据结构来转移,存f[i]-i的最小值。如果第i行这里是1,就把数据结构的这里改成f[i]-i,查询的时候查询这一行是1的地方的最小值,再-1就可以了。最终答案就是f[n+1]+n+1

    记录方案就是DO经典套路,转移的同时记。可以把来源和最值一起扔到线段树里来存。然后我写的时候修改不是区间取min而是区间覆盖,因为我赛时想的是靠后的转移一定更优。赛后证了一下,是对于k<j这两个可行的转移,一定可以把j到k的中间这些行全都删了,也就是f[j]<=f[k]+(j-k-1),也就是f[j]-j<=f[k]-k-1<f[k]-k,所以越靠后的转移越优。

    值域是1e9来着所以要离散化一下。我之前动态开点结果MLE on 1

      1 /**
      2  *  There is no end though there is a start in space. ---Infinity.
      3  *  It has own power, it ruins, and it goes though there is a start also in the star. ---Finite.
      4  *  Only the person who was wisdom can read the most foolish one from the history.
      5  *  The fish that lives in the sea doesn't know the world in the land.
      6  *  It also ruins and goes if they have wisdom.
      7  *  It is funnier that man exceeds the speed of light than fish start living in the land.
      8  *  It can be said that this is an final ultimatum from the god to the people who can fight.
      9  *  
     10  *  Steins;Gate
     11 **/
     12 
     13 #include <bits/stdc++.h>
     14 typedef long long LL;
     15 inline char gc() {
     16     return getchar();
     17     static char buf[100000], *p1 = buf, *p2 = buf;
     18     if(p1 == p2) {
     19         p2 = (p1 = buf) + fread(buf, 1, 100000, stdin);
     20     }
     21     return (p1 == p2) ? EOF : *p1++;
     22 }
     23 
     24 template <typename T>
     25 inline void read(T& x) {
     26     x = 0;
     27     char c(gc());
     28     int f(1);
     29     while(c < '0' || c > '9') {
     30         if(c == '-') {
     31             f = -1;
     32         }
     33         c = gc();
     34     }
     35     while(c >= '0' && c <= '9') {
     36         x = x * 10 + c - '0';
     37         c = gc();
     38     }
     39     x *= f;
     40 }
     41 
     42 inline LL read() {
     43     LL x;
     44     read(x);
     45     return x;
     46 }
     47 
     48 const int N = 300010;
     49 
     50 struct Node {
     51     int l, r;
     52 };
     53 struct Data {
     54     int val, id;
     55     Data(int V = 0, int I = 0)
     56         : val(V), id(I) {}
     57 };
     58 std::vector<Node> v[N];
     59 int n, m, tot = 1, X[N * 2], top;
     60 Data f[N];
     61 Data Min[N * 8], tag[N * 8];
     62 Data exmin(Data a, Data b) {
     63     if(!a.id)
     64         return b;
     65     if(!b.id)
     66         return a;
     67     if(a.val < b.val) {
     68         return a;
     69     }
     70     return b;
     71 }
     72 inline void pushdown(int o) {
     73     if(tag[o].id) {
     74         int ls = o << 1, rs = o << 1 | 1;
     75         tag[ls] = Min[ls] = tag[o];
     76 
     77         tag[rs] = Min[rs] = tag[o];
     78 
     79         tag[o] = Data(0, 0);
     80     }
     81 }
     82 inline void pushup(int o) {
     83     Min[o] = exmin(Min[o << 1], Min[o << 1 | 1]);
     84 }
     85 void change(int L, int R, int v, int id, int l, int r, int o) {
     86     if(L <= l && r <= R) {
     87         tag[o] = Min[o] = Data(v, id);
     88         return;
     89     }
     90     pushdown(o);
     91     int mid = (l + r) >> 1;
     92     if(L <= mid) {
     93         change(L, R, v, id, l, mid, o << 1);
     94     }
     95     if(mid < R) {
     96         change(L, R, v, id, mid + 1, r, o << 1 | 1);
     97     }
     98     pushup(o);
     99 }
    100 
    101 Data getMin(int L, int R, int l, int r, int o) {
    102     if(L <= l && r <= R) {
    103         return Min[o];
    104     }
    105     pushdown(o);
    106     int mid = (l + r) >> 1;
    107     Data ans(-1, 0);
    108     if(L <= mid) {
    109         ans = getMin(L, R, l, mid, o << 1);
    110     }
    111     if(mid < R) {
    112         ans = exmin(ans, getMin(L, R, mid + 1, r, o << 1 | 1));
    113     }
    114     return ans;
    115 }
    116 
    117 int main() {
    118     // printf("%d
    ", (sizeof(ls) + sizeof(rs) + sizeof(tag) + sizeof(Min) + sizeof(v)) / 1048576);
    119 
    120     read(n);
    121     read(m);
    122     for(int i = 1, x, l, r; i <= m; i++) {
    123         read(x);
    124         read(l);
    125         read(r);
    126         v[x].push_back(Node{l, r});
    127         X[++top] = l;
    128         X[++top] = r;
    129     }
    130     std::sort(X + 1, X + top + 1);
    131     top = std::unique(X + 1, X + top + 1) - X - 1;
    132     for(int i = 1; i <= n; i++) {
    133         for(int j = 0; j < v[i].size(); j++) {
    134             v[i][j].l = std::lower_bound(X + 1, X + top + 1, v[i][j].l) - X;
    135             v[i][j].r = std::lower_bound(X + 1, X + top + 1, v[i][j].r) - X;
    136         }
    137     }
    138     for(int i = 1; i <= n; i++) {
    139         for(Node node : v[i]) {
    140             int L = node.l, R = node.r;
    141             f[i] = exmin(f[i], getMin(L, R, 1, top, 1));
    142         }
    143         f[i].val--;
    144         for(Node node : v[i]) {
    145             int L = node.l, R = node.r;
    146             change(L, R, f[i].val, i, 1, top, 1);
    147         }
    148         // printf("f %d = %d from %d 
    ", i, f[i].val + i, f[i].id);
    149     }
    150     f[n + 1] = Min[1];
    151     f[n + 1].val--;
    152     printf("%d
    ", f[n + 1].val + n + 1);
    153     int p = n + 1;
    154     while(p) {
    155         int nexP = f[p].id;
    156         for(int i = nexP + 1; i < p; i++) {
    157             printf("%d ", i);
    158         }
    159         p = nexP;
    160     }
    161 
    162     return 0;
    163 }
    AC代码
  • 相关阅读:
    c#结构体、打他table、excel、csv互转
    WPF 自定义图表(柱状图,曲线图)
    NemaStudio船舶模拟软件下载及破解
    点双连通分量
    HDU4612 Warm up
    边双连通分量
    [Jsoi2010]连通数
    Intern Day73
    Intern Day72
    Intern Day70
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/15124464.html
Copyright © 2011-2022 走看看