其他分享
首页 > 其他分享> > hdu多校第四场补题

hdu多校第四场补题

作者:互联网

H - Lawn of the Dead HDU - 6992

用每一行可以走到的区间去更新下一行可以走到的区间,二分找到上一行的可走区间中 左端点小于当前区间的左端点,且左端点距离当前区间的左端点的距离最近的区间,判两个区间是否相交,根据相交情况更新当前行的可走区间,代码方面需要注意一些细节。
AC代码:

#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 100;

typedef long long ll;
vector<int> edge[N];
int up[2][N], dw[2][N];

void solve() {
    int n, m, k;
    ll ans = 0;
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; ++ i) edge[i].clear(), edge[i].push_back(m + 1);
    while(k --) {
        int x, y;
        scanf("%d%d", &x, &y);
        edge[x].push_back(y);
    }

    int s = 1, e;
    int cnt1 = 0, cnt2 = 0;
    sort(edge[1].begin(), edge[1].end());
    e = edge[1][0] - 1;
    up[0][cnt1] = s, dw[0][cnt1 ++] = e;
    ans += e - s + 1;
    int prex;
    for(int i = 2; i <= n; ++ i) {
        prex = 0;
        int temp = i % 2;
        s = 1, e = 0;
        sort(edge[i].begin(), edge[i].end());
        for(int j = 0; j < edge[i].size(); ++ j) {
            s = prex + 1;
            e = edge[i][j] - 1;
            prex = edge[i][j];
            // for(int pp = 0;pp < cnt1;pp++){
                // printf("%d %d **\n",up[temp][j],dw[temp][j]);
            // }
            if(s > e) continue;
            int now = upper_bound(up[temp], up[temp] + cnt1, s) - up[temp];
            now --;

            if(now < 0 || dw[temp][now] < s) {
                now ++;
                if(now >= cnt1 || up[temp][now] > e) continue;
                s = up[temp][now];
            }

            ans += e - s + 1;
            up[(i - 1) % 2][cnt2] = s, dw[(i - 1) % 2][cnt2 ++] = e;
        }
        cnt1 = cnt2;
        cnt2 = 0;
    }
    printf("%lld\n", ans);
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("cf.in", "r", stdin);
        freopen("cf.out", "w", stdout);
    #endif
    int t;
    scanf("%d", &t);
    while(t --) {
        solve();
    }
    return 0;
}

标签:hdu,第四场,temp,int,up,edge,补题,cnt1,now
来源: https://blog.csdn.net/weixin_45925735/article/details/119255795