zoukankan      html  css  js  c++  java
  • 【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("
    ");
                for(int i = ly; i < ry-1; i ++)
                    printf("%d ", i - 1000);
                printf("%d", ry - 1001);
                printf("
    ");
            } else {
                int sum = rx - lx;
                for(int i = lx; i < rx-1; i ++)
                    printf("%d ", i - 1000);
                printf("%d", rx - 1001);
                printf("
    ");
                for(int i = 1; i < sum; i ++)
                    printf("%d ", ly - 1000);
                printf("%d", ly - 1000);
                printf("
    ");
            }
            printf("%d
    ", 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;
    } 
  • 相关阅读:
    Flink批处理读取Hive写入MySql
    数组与链表的优缺点
    Flink任务暂停重启
    Flink优化总结
    Flink集群监控
    flink连接器-流处理-读写redis
    Flink连接器-批处理-读写Hbase
    flink on yarn
    java的常量定界符
    特殊注释的使用
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9747446.html
Copyright © 2011-2022 走看看