Codeforces Round #310 (Div. 2)补题记录

前三题:556A 556B 556C

A题就是数一下\(0\)\(1\)的个数求个最小值,B模拟一下就可以了,C题按照题目大意直接暴力,注意拆一次和装一次各算\(1s\),题目没有说太清楚。

D.556D

经典弱化版扫描线。

大意:给你\(n\)个线段,\(m\)个桥,在\(m\)中选择\(n-1\)个,连接相邻的线段。问能不能全连上,如果可以就按照连接的顺序输出桥的编号

思路:

首先第一个样例的图可以是这样子:

suETmT。png

转换一下思路,桥的长度是\(x\),连接两个线段最小的长度是\(l\),最大是\(r\)的话。那么如果这个桥可以连接这两个线段,条件就是:\(l\leq x \leq r\)

于是,就变成了判断一个点是否在一个线段内。经典扫描线\(O(n)\)做法。

上面那个图就成了这样:

suV6jx。png

\([1,4]\)\([7,8]\)对应着\([3,7]\),etc.

然后对于桥,优先匹配的是左端点最远的线段。这个地方画一下图就会发现,反例都是画不出来的

简述一下扫描线的思路:

首先将线段起点,终点,以及桥的点排序,然后从小到大遍历。遇到起点,就将其记入集合;遇到终点,就寻找匹配的线段,然后在集合内删除该线段。遇到桥,就寻找匹配的线段,然后记录线段和桥的编号,然后在集合内删除该线段的起点。

详细看代码:

#if __cplusplus >= 201103L
#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
#else
#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <string.h>
#include <vector>
#endif

using namespace std;
#define inf __INT_MAX__
#define enf INT_MIN
#define INF LLONG_MAX
#define ENF LLONG_MIN

const int MAXN = 2e5 + 10;
const double pi = acos(-1.0);
const double eps = 1e-6;
typedef long long ll;
typedef unsigned long long ull;
#define zhengfu(x) ((x > eps) - (x < -eps))

struct vec {
    ll l, r;
    int pos;
    bool operator<(const vec it)const {
        //按照左端点,右端点,类型依次排列
        return l == it.l ? (r == it.r ? pos < it.pos : r < it.r) : l < it.l;
    }
};
int ans[MAXN];
int main() {
    int n, m;
    cin >> n >> m;
    vec vi;
    cin >> vi.l >> vi.r;
    vector<vec> v, a(n);
    set<vec> st;
    for (int i = 1; i < n; i++) {
        vec vt;
        cin >> vt.l >> vt.r;
        a[i] = vec{vt.r - vi.l, 1, i};	//用1表示终点
        v.push_back(vec{vt.l - vi.r, -1, i});	//-1表示起点
        v.push_back(a[i]);
        vi = vt;
    }
    for (ll i = 0, x; i < m; i++) {
        cin >> x;
        v.push_back(vec{x, 0, i + 1});	//0表示桥
    }
    sort(v.begin(), v.end());
    for (auto it : v) {
        if (it.r == -1)	//遇到起点将该线段记入集合
            st.insert(a[it.pos]);
        else if (it.r == 1)	//遇到终点就将线段删除
            st.erase(a[it.pos]);
        else if (st.size()) {	//遇到桥,将set里最远的起点删除
            int pos = st.begin()->pos;
            ans[pos] = it.pos;
            st.erase(st.begin());
        }
    }
    bool f = 0;
    for (int i = 1; i < n; i++)
        if (!ans[i])
            f = 1;
    if (!f) {
        cout << "Yes" << endl;
        for (int i = 1; i < n; i++)
            cout << ans[i] << ' ';
    } else
        cout << "No" << endl;
}

E.556E

很鬼畜的题目,也很直白

sumRbV.png

\(n\times n\)的巧克力,吃掉逆对角线下方的所有巧克力。然后每次在逆对角线上选择一个格子和一个方向,一直吃到被吃过的地方。问每次选择能吃多少个,\(q\)次询问。

思路:

  • 选择一行或者一列吃之后,我们就直接记录每行最右边的格子位置和每列最下边的格子位置,这样就是\(O(1)\)的询问
  • 选择第\(i\)行,那么就是该行\(U[y_i]=x_i\),列就是\(L[x_j]=y_i,j\in(1,n)\)
  • 相应第\(i\)列也如此,该行\(L[x_i]=y_i\),列就是\(U[y_j]=x_i,j\in(1,n)\)

那么时间复杂度就是\(O(qn)\)显然超时。

下面考虑用线段树记录数据。众所周知,线段树的更新和查询都是\(O(\log{n})\)

我们将询问的\(x\)\(y\)都记录下来,离散化排序后用来进行线段树的建立,然后对于每次询问,每次查询更新就是\(O(\log{q})\)

总复杂度就是\(O(q\log{q})\)

注意这里的线段树需要打\(lazy~tag\)

官方题解只记录了\(x\),没太理解,于是我就按照自己的习惯写的

#if __cplusplus >= 201103L
#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
#else
#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <string.h>
#include <vector>
#endif

using namespace std;
#define inf __INT_MAX__
#define enf INT_MIN
#define INF LLONG_MAX
#define ENF LLONG_MIN

const int MAXN = 4e5 + 10;
const double pi = acos(-1.0);
const double eps = 1e-6;
typedef long long ll;
typedef unsigned long long ull;
#define zhengfu(x) ((x > eps) - (x < -eps))

#define l(p) (p << 1)
#define r(p) (p << 1 | 1)

struct node {
    ll d;
    ll lazy;
    ll L, R;
} treeL[MAXN << 2], treeU[MAXN << 2];
void built(node tree[], int p, int l, int r) {
    tree[p].L = l, tree[p].R = r;
    tree[p].lazy = 0;
    tree[p].d = 0;
    if (l != r) {
        int mid = (l + r) >> 1;
        built(tree, l(p), l, mid);
        built(tree, r(p), mid + 1, r);
    }
}
void push(node tree[], int p) {
    tree[p].d = max(tree[p].d, tree[p].lazy);
    if (tree[p].L != tree[p].R) {
        tree[l(p)].lazy = max(tree[p].lazy, tree[l(p)].lazy);
        tree[r(p)].lazy = max(tree[p].lazy, tree[r(p)].lazy);
    }
}
int query(node tree[], int p, int k) {
    push(tree, p);
    if (k == tree[p].L && tree[p].L == tree[p].R)
        return tree[p].d;
    int mid = tree[p].L + tree[p].R >> 1;
    return k > mid ? query(tree, r(p), k) : query(tree, l(p), k);
}
void update(node tree[], int p, int l, int r, int k) {
    push(tree, p);
    if (tree[p].L == l && tree[p].R == r) {
        tree[p].lazy = k;
        return;
    }
    int mid = tree[p].L + tree[p].R >> 1;
    if (r <= mid)
        update(tree, l(p), l, r, k);
    else if (l > mid)
        update(tree, r(p), l, r, k);
    else
        update(tree, l(p), l, mid, k), update(tree, r(p), mid + 1, r, k);
}
struct vec {
    int x, y;
    char ch;
};
int main() {
    int n, q;
    cin >> n >> q;
    vector<vec> v(q);          //x,y,u/l
    vector<pair<int, char>> a; //用于离散的数组
    for (auto &it : v) {
        cin >> it.x >> it.y >> it.ch;
        a.push_back(make_pair(it.x, it.ch));
        a.push_back(make_pair(it.y, it.ch));
    }
    //离散
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end(), [](pair<int, char> b, pair<int, char> c) {
                return b.first == c.first;
            }),
            a.end());
    
    map<int, int> mp;
    int len = a.size();
    for (int i = 0; i < a.size(); i++)
        mp[a[i].first] = i + 1;

    int rootL = 1, rootU = 1;
    built(treeL, rootL, 0, len + 1);
    built(treeU, rootU, 0, len + 1);

    for (auto it : v) {
        int xx = mp[it.x], yy = mp[it.y];
        if (it.ch == 'U') {
            int ll = query(treeU, rootU, xx);
            update(treeL, rootL, ll, yy, xx);
            update(treeU, rootU, xx, xx, yy);
            if (ll != 0)
                printf("%d\n", a[yy - 1].first - a[ll - 1].first);
            else
                printf("%d\n", a[yy - 1].first);
        } else {
            int ll = query(treeL, rootL, yy);
            update(treeU, rootU, ll, xx, yy);
            update(treeL, rootL, yy, yy, xx);
            if (ll != 0)
                printf("%d\n", a[xx - 1].first - a[ll - 1].first);
            else
                printf("%d\n", a[xx - 1].first);
        }
    }
}

施法保佑

/**
       爆ぜろリアル!弾けろシナプス!パニッシュメント・ディス・ワールド!     
                                                                          
                         ';!!!:`                                        
                     .;%%%%$$$$%%%;.                                    
                   .;$%;.         :%;.                                  
                  `||`              :!.                                 
                 .!:                 ::                                 
                 :;                  .`.                                
                 '`                   ..                                
                 ``                   .                                 
                  ..                 ..                                 
                                     ..                                 
                         `;||!:';|%$$$%%%$$%|;'.                        
                     '|%%%%%%%%%%%%%%%%%%%%%%%%%%%%|:.                  
                   ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$|:               
                .:!%%%%%%%%%%|!|%%%%$$&$$$%%%%%%%%%%%%%%%%|'   `:'.     
               '!|%%%%%||%%%%%%%%%%%$&&&$%%%%%$$$%%%%%%%%%%%|'':':'.    
             `|%%%%%%%%%%%%%$%%%%%%%$&&&&$$%%%$$$%%%%%%%%%%%%|;:::'::':`
            :%%%%%%$$%%%$$%%$%%%%%%%$&&&&&$$%%|%$%%%|!|%%%%%$!'::::;|!:'.
          .;$%%%%%$$%%%$$%%$%%%%%%%%$&&&&&$$$%%$$$%%%!!%$%%%%!::!%%%%|;'.
         .;%$%%%$$$%%%$$%%||%$$%%%%$$&&&&&&$$%%$$%%%%%%%$&&&$%$$$$%%%%|:.
         ;%%%%%$$$%%$&$%%!:!$$$%%%%$&$||&&&&$$%$$$%%%%%%$$$%%%%$$$$%%%|'
        :%%$%%$$$$%$&&$%!`'|$&$%%%%$&|`.!&&&&$%$$$%%%%%%%$%%%%%%$$$$%%%;
       `!%|%%%$&$%%$&$$|'.'|&&$%%%%$%|!'.:$&&&$$$$%%%%%%%%%%%%%%$$$$%%%|`
       ;%':%%$&&$%$&|!|'.`:|&&$%%%$$|'''``'%&&&$$$%%%%%%%%%%%%%%$&&$%%%%:
      `;' ;%%$&$%%$%;;:   .:!%$%%%$|`  ..  .!&&&$$$%%$%%%$%$$%$$%$&$%%%$;
      '' .!%$&&$$%$;`:'      `!%%%%:.... ....:$&$$$%$$%%$$$$$%$$%$&$%%%%;
      .. .;%$&&&$%|:.        ...;%|'..........'|$%%%$$%%$$&&$%$$%%%$%%%$;
          ;$$&&&$%!`        .`....'`.... ......`!%%%$$%%$&&&$$&&$!!$%%%$:
          '%$&&&&$!`.       .`........``.......`!%%$$$%$&&&&$$&&$;;$%%%%'
          '|$&&&&!``..```.  ........`|@@|'....`:|%%$$%%$&&&&$$&&$':$%%%|`
          `|$&&&&$'  .``````'''::`..........``.:%%$&$%|'`!&&$$&&%':%%%%;.
           ;$$&&|;!:`...........  .':`....`````!%$&&$%|;';&&&%|%%';%%%%:
           '%$&$:  ...................`''`...`:%%$&$$!`..!&&&$;`:;|%%%!`
            ;$&&%:.....................  .':``!%$&&$;...:$&%'`;' ;%%%%: 
            .;$&&&$:..........`'............`!%$&&&;..'%&&!     `!%%%:  
             .':|&&&|''`..............   ...'|$&&$||$&&&|`      :|'``   
                  .!%: `|$%|!:'`.........`:!%$&&&&&$;''.       `.       
                  .:!%$%||||||%%$$$$$$$$$%$%%$$$%%:.                    
             `!%$%%%%%%%|||||||||||%|||||||%%%%%$%%%%|:                 
          '%%%%%%%%%%%%||||||||!!|||||||||||%$$%%%%%%%%$%:              
         :%$$$%%%$%$$%||||||||!;%%||||||||%%%%%%%%%%%%%%%%|'            
         .;$%%%%$$$$$%%|||||%$$$$$%||||||||%$$%%%%%%%%%%%%%%'           
          .!%%%%%%$$%%$%%|||||;;%||||||||%$$&&|!%$$%%%$$$$$%;.          
           .!%%%%%%%%%%%%%%$%||%%%%%%%%%%%$&$$;`;%%%%%%%%$$!.           
             :%%%%%%%%%%%%%%||%%%%%%%%%%%$$$%%%%%%%%%%%%%|'             
                :%%%%%%%%%%$$%%%%%%%%%%%%%%%;`;%%%%%%%|:                
               .;%%%%%%%%%%%%%%%%%%%%%%%%%%%:..:|%%%!.                  
               '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|;:`                       
               ;$%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%'                       
              `|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$;                       
              .:!%$%%%%%%%%%%%%%%%%%%%%%%%%%%%%$!.                      
              ;!';%%%%%%%%%%%%%%%%%%%%%!:`.  `|$%'                      
             .;%%%%%%%%%%%||%%%%%%%%%|:';|%$%%%%%;.                     
             .!%%%%%%%%%%%%$$%%%%%%%%%%%%%%%%%%%%%'                     
             .!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$;.                    
             .;%%%%%%%%%%%%$%%%%%%%%%%%%%%%%%%%%%%%'                    
              ;%$$%%%%%%%%$$$$%%%%%%%%%%%%%%%%%%%%%'                    
             `|$&$%%%%%%$%$$$%%%%%%%%%%%%$%%%%%$&%%!`                   
             :%$&$%%||%%%%$$%%%$%%%%%$$!:|%||%%$&$%%!`                  
**/
posted @ 2021-01-08 15:17  CrossAutomaton  阅读(102)  评论(0编辑  收藏  举报