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\n", sum);
}
return 0;
}
为什么要是while(ln[cur1].next <= cur0 && ln[cur2].next <= n)
而不能是while(cur1 < cur0 && cur2 < n)
呢?