C - Maximal Value
遍历比较一下相邻的值
D - Face Produces Unhappiness
反向思维,考虑不开心的点
字符串可以规约成RR...RLL...LRR...RL...L这样相间的情况
每次操作只有把整段的R或者L反向,才能减少不开心的点
有几种不同的情况
RLRLR
LRLR
RLRL
LRLRL
2.3两种情况是一样的
分情况考虑即可
python
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @author : yhdu@tongwoo.cn
# @desc :
# @file : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(50005)
def main():
items = sys.version.split()
if items[0] == '3.10.6':
fp = open("in.txt")
else:
fp = sys.stdin
n, k = map(int, fp.readline().split())
s = fp.readline().strip()
l, r = [], []
last = '#'
t = 0
for i in range(n):
if last != s[i]:
if last == 'L':
l.append(t)
elif last == 'R':
r.append(t)
t = 1
else:
t += 1
last = s[i]
if last == 'L':
l.append(t)
else:
r.append(t)
if len(l) == len(r): # LRLRLR or RLRLRL
if k >= len(r):
ans = n - 1
else:
c = max(0, len(r) - 1 - k) * 2
ans = n - 2 - c
elif len(l) == len(r) + 1:
if k >= len(r):
ans = n - 1
else:
c = max(0, len(r) - k) * 2
ans = n - 1 - c
else:
if k >= len(l):
ans = n - 1
else:
c = max(0, len(l) - k) * 2
ans = n - 1 - c
print(ans)
if __name__ == "__main__":
main()
E - Second Sum
这类题目的通解是计算每个点能取到几个区间,将贡献和累加起来
记录位置列表为pos,即pos[a[i]] = i
需要维护一个双向链表,记录下每个位置的左边和右边。从小到大遍历数字i的位置,遍历完之后将i的位置删除。这样可以保证链表中每个位置代表的数字都比当前的数大。
比如例子 2 3 1中
pos[1]=3 pos[2]=1 pos[3]=2
1的位置是3,开始时3的左边比它大的位置是2,右边是位置4(边界)
因为当右边取边界之内的数字时(也就是只取到位置3)
左边可以取位置2,但是不能取到位置1,因为从小到大取的原因,位置1的数2比当前的数1更大。也就是只能取一次位置。
最后得到的位置列表是[2,3],代表原始列表是[3,1]
python
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @author : yhdu@tongwoo.cn
# @desc :
# @file : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(50005)
def main():
items = sys.version.split()
if items[0] == '3.10.6':
fp = open("in.txt")
else:
fp = sys.stdin
n = int(fp.readline())
a = list(map(int, fp.readline().split()))
a = [0] + a
lmax = [0] * (n + 2)
rmax = [0] * (n + 2) # link pos, bigger than current
pos = [0] * (n + 2)
for i in range(1, n + 1):
lmax[i] = i - 1
rmax[i] = i + 1
pos[a[i]] = i
ans = 0
for i in range(1, n + 1):
p = pos[i]
l1, r1 = lmax[p], rmax[p]
l2, r2 = lmax[l1], rmax[r1]
c1 = max(0, (p - l1) * (r2 - r1))
c2 = max(0, (r1 - p) * (l1 - l2))
ans += i * (c1 + c2)
rmax[l1] = r1
lmax[r1] = l1
print(ans)
if __name__ == "__main__":
main()