• 2020年“远光杯”粤澳计算机程序设计大赛网络资格赛


    捕鱼

    看起来像是一个LIS,套个线段树加速一下就可以了。

    Trie

    稍微卡空间,用数组和map都不行,用vector建图,空间消耗大概减少了10倍。不过要记得sort。

    任务安排

    为什么要按学生做的时间从大到小排呢?

    H题

    struct ListNode {
        int next;
        int prev;
        int val;
        int pos;
    } ln[10005];
    
    int a[10005];
    pii ax[10005];
    
    int Q[10005];
    int front, back;
    
    int main() {
    #ifdef KisekiPurin
        freopen("KisekiPurin.in", "r", stdin);
    #endif // KisekiPurin
        int t;
        scanf("%d", &t);
        for(int ti = 1; ti <= t; ++ti) {
            printf("Case #%d: ", ti);
            int n, x;
            scanf("%d%d", &n, &x);
            ln[0].pos = 0;
            ln[0].next = 1;
            ln[n + 1].pos = n + 1;
            ln[n + 1].prev = n;
            for(int i = 1; i <= n; ++i) {
                scanf("%d", &a[i]);
                ln[i].next = i + 1;
                ln[i].prev = i - 1;
                ln[i].pos = i;
                ln[i].val = a[i];
                ax[i] = {a[i], i};
            }
            if(x > n) {
                puts("0");
                continue;
            }
            sort(ax + 1, ax + 1 + n);
            ll sum = 0;
            for(int i = 1; i <= n - x + 1; ++i) {
                int cur0 = ax[i].second;
                int cur1 = cur0;
                for(int cx = x; cx > 1 && ln[cur1].prev != 0; --cx)
                    cur1 = ln[cur1].prev;
                int cur2 = cur1;
                front = 1;
                back = 0;
                Q[++back] = ln[cur2].val;
                for(int cx = x; cx > 1; --cx) {
                    cur2 = ln[cur2].next;
                    while(front <= back && Q[back] < ln[cur2].val)
                        Q[--back];
                    Q[++back] = ln[cur2].val;
                }
    
                int Rlen = (ln[ln[cur2].next].pos - ln[cur2].pos);
                int Llen = (ln[cur1].pos - ln[ln[cur1].prev].pos);
                sum += 1ll * Llen * Rlen * (ax[i].first ^ Q[front]);
    
                while(ln[cur1].next <= cur0 && ln[cur2].next <= n) {
                    if(Q[front] == ln[cur1].val)
                        Q[++front];
                    cur1 = ln[cur1].next;
                    cur2 = ln[cur2].next;
                    while(front <= back && Q[back] < ln[cur2].val)
                        Q[--back];
                    Q[++back] = ln[cur2].val;
    
                    int Rlen = (ln[ln[cur2].next].pos - ln[cur2].pos);
                    int Llen = (ln[cur1].pos - ln[ln[cur1].prev].pos);
                    sum += 1ll * Llen * Rlen * (ax[i].first ^ Q[front]);
                }
                ln[ln[cur0].prev].next = ln[cur0].next;
                ln[ln[cur0].next].prev = ln[cur0].prev;
            }
            printf("%lld
    ", sum);
        }
        return 0;
    }
    

    为什么要是while(ln[cur1].next <= cur0 && ln[cur2].next <= n)而不能是while(cur1 < cur0 && cur2 < n)呢?

  • 相关阅读:
    异步任务AsyncTask
    巧用TextView实现分隔线
    android系统的常用权限
    浅析对话框AlertDialog
    LinearLayout中的layout_weight属性详解
    CLOB大数据对象
    模糊查询demo
    ES6 箭头函数
    ES6中数组求和,求平均数方法( reduce )
    ES6中数组方法( every 和 some )
  • 原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12775295.html
Copyright © 2020-2023  润新知