【10.6校内测试】【小模拟】【hash+线段树维护覆盖序列】

一开始看到题就果断跳到T2了!!没想到T2才是个大坑,浪费了两个小时QAQ!!

就是一道小模拟,它怎么说就怎么走就好了!

为什么要用这么多感叹号!!因为统计答案要边走边统计!!如果每个数据都扫一遍2000*2000就炸了!!!

我爆哭QAQ再也不用stl的max叻!!(然而一定会被打脸)我的100分QAQAQAQ

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

int k, n;
int vis[2005][2005];
char s[105];

int main() {
    freopen("block.in", "r", stdin);
    freopen("block.out", "w", stdout);
    int T;
    scanf("%d", &T);
    while(T --) {
        scanf("%d", &k);
        scanf("%s", s);
        int now = 0;
        memset(vis, 0, sizeof(vis));
        vis[1000][1000] ++;
        int lx = 1000, ly = 1000, rx = 1001, ry = 1001;
        int ans = 0;
        for(int i = 0; i < strlen(s); i ++) {
            char opt = s[i];
            if(opt == 'N') {
                if(now) {
                    if(rx == lx + 1) {
                        vis[lx][ly+k] ++;
                        if(vis[lx][ly+k] > ans)    ans = vis[lx][ly+k];
                        ly = ry, ry ++;
                        now = 0;
                    } else {
                        for(int p = lx; p < rx; p ++) {
                            vis[p][ry] ++;
                            if(vis[p][ry] > ans)    ans = vis[p][ry];
                        }
                        ly ++, ry ++;
                    }
                } else {
                    for(int p = ly + 1; p <= ly + k; p ++) {
                        vis[lx][p] ++;
                        if(vis[lx][p] > ans)    ans = vis[lx][p];
                    }
                    ly ++; ry += k;
                    now = 1;
                }
            } else if(opt == 'S') {
                 if(now) {
                     if(rx == lx + 1) {
                         vis[lx][ly-1] ++;
                         if(vis[lx][ly-1] > ans)    ans = vis[lx][ly-1];
                         ly --; ry = ly + 1;
                         now = 0;
                     } else {
                         for(int p = lx; p < rx; p ++) {
                             vis[p][ly-1] ++;
                             if(vis[p][ly-1] > ans)    ans = vis[p][ly-1];
                         }
                         ly --; ry --;
                     }
                 } else {
                     for(int p = ly - 1; p >= ly - k; p --) {
                         vis[lx][p] ++;
                         if(ans < vis[lx][p])    ans = vis[lx][p];
                     }
                     ry = ly; ly = ly - k;
                     now = 1;
                 }
            } else if(opt == 'W') {
                if(now) {
                    if(rx == lx + 1) {
                        for(int p = ly; p < ry; p ++) {
                            vis[lx-1][p] ++;
                            if(vis[lx-1][p] > ans)    ans = vis[lx-1][p];
                        }
                        lx --; rx --;
                    } else {
                        vis[lx-1][ly] ++;
                        if(vis[lx-1][ly] > ans)    ans = vis[lx-1][ly];
                        lx --; rx -= k;
                        now = 0;
                    }
                } else {
                    for(int p = lx - k; p < lx; p ++) {
                        vis[p][ly] ++;
                        if(vis[p][ly] > ans)    ans = vis[p][ly];
                    }
                        
                    lx -= k; rx --;
                    now = 1;
                }
            } else {
                if(now) {
                    if(rx == lx + 1) {
                        for(int p = ly; p < ry; p ++) {
                            vis[lx+1][p] ++;
                            if(vis[lx+1][p] > ans)    ans = vis[lx+1][p];
                        }
                        lx ++; rx ++;
                    } else {
                        vis[lx+k][ly] ++;
                        if(vis[lx+k][ly] > ans)    ans = vis[lx+k][ly];
                        lx += k; rx ++;
                        now = 0;
                    }
                } else {
                    for(int p = lx + 1; p < rx + k; p ++) {
                        vis[p][ly] ++;
                        if(vis[p][ly] > ans)    ans = vis[p][ly];
                    }
                    lx ++; rx += k;
                    now = 1;
                }
            }
        }
        if(rx == lx + 1) {
            int sum = ry - ly;
            for(int i = 1; i < sum; i ++)
                printf("%d ", lx - 1000);
            printf("%d", lx - 1000);
            printf("\n");
            for(int i = ly; i < ry-1; i ++)
                printf("%d ", i - 1000);
            printf("%d", ry - 1001);
            printf("\n");
        } else {
            int sum = rx - lx;
            for(int i = lx; i < rx-1; i ++)
                printf("%d ", i - 1000);
            printf("%d", rx - 1001);
            printf("\n");
            for(int i = 1; i < sum; i ++)
                printf("%d ", ly - 1000);
            printf("%d", ly - 1000);
            printf("\n");
        }
        printf("%d\n", ans);
    }
    return 0;
}

这道题暴力分拿的太爽了,15分钟敲出来70分成了救命稻草QAQAQ

区间修改考虑线段树。

因为目标的覆盖序列只有一个,就是1~k。其他的序列都不合法,怎么才能在最后快速判断是否合法呢?

想到$hash$,每次覆盖相当于在$hash$序列中加一个数,在线段树上转化成了$*A+B$($A$就是$base$,$B$就是新增的数),于是就可以维护了。

最后查询$Dfs$将每个叶子节点的$hash$值存下来即可。

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

int n, k, t;
unsigned int tag1[800005], tag2[800005];
unsigned int TR[800005], has[200005];

void build(int nd, int l, int r) {
    tag1[nd] = 1; tag2[nd] = 0;
    if(l == r) return ;
    int mid = (l + r) >> 1;
    build(nd << 1, l, mid);
    build(nd << 1 | 1, mid + 1, r);
}

void push_down(int nd, int l, int r) {
    if(tag1[nd] != 1 || tag2[nd] != 0) {
        TR[nd<<1] = TR[nd<<1] * tag1[nd] + tag2[nd];
        TR[nd<<1|1] = TR[nd<<1|1] * tag1[nd] + tag2[nd];
        tag1[nd<<1] = tag1[nd] * tag1[nd<<1];
        tag1[nd<<1|1] = tag1[nd] * tag1[nd<<1|1];
        tag2[nd<<1] = tag1[nd] * tag2[nd<<1] + tag2[nd];
        tag2[nd<<1|1] = tag1[nd] * tag2[nd<<1|1] + tag2[nd];
        tag1[nd] = 1; tag2[nd] = 0;
    }
}

void modify(int nd, int l, int r, int L, int R, int d) {
    if(l >= L && r <= R) {
        TR[nd] = TR[nd] * base + d;
        tag2[nd] = tag2[nd] * base + d;
        tag1[nd] = tag1[nd] * base;
        return ;
    }
    push_down(nd, l, r);
    int mid = (l + r) >> 1;
    if(L <= mid)    modify(nd << 1, l, mid, L, R, d);
    if(R > mid)        modify(nd << 1 | 1, mid + 1, r, L, R, d);
    
}

void query(int nd, int l, int r) {
    if(l == r) {
        has[l] = TR[nd];
        return ;
    }
    push_down(nd, l, r);
    int mid = (l + r) >> 1;
    query(nd << 1, l, mid);
    query(nd << 1 | 1, mid + 1, r);
}

int main() {
    freopen("deco.in", "r", stdin);
    freopen("deco.out", "w", stdout);
    scanf("%d%d%d", &n, &k, &t);
    build(1, 1, n);
    for(int i = 1; i <= t; i ++) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        modify(1, 1, n, a, b, c);
    }
    query(1, 1, n);
    int h = 0;
    for(int i = 1; i <= k; i ++)
        h = h * base + i;
    int ans = 0;
    for(int i = 1; i <= n; i ++)
        if(has[i] == h)    ans ++;
    printf("%d", ans);
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/wans-caesar-02111007/p/9747446.html
今日推荐