粤澳计算机大赛,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)呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值