cf5 E. Bindian Signalizing
题意:
给定长为 的环,对环上两点 ,若存在 到 的弧,弧中的数均不大于 或 ,则称 和 可以互相看到。求可以互相看到的位置对数。
思路:
拆环成链,把最大的数 放在链头(可能不止一个最大的,但没关系)
在链尾也插一个
对环中的位置 ,求左边最近的大于 的位置 和右边最近的大于 的位置 ,则有两对 和 。另外 中所有与 相等的位置 也会与 配对,为了避免重复计数我们统计 中 的数量,记为
void sol() {
int n; cin >> n;
vector<int> a(n); for(int &x : a) cin >> x;
rotate(a.begin(), max_element(a.begin(),a.end()), a.end());
a.push_back(a[0]);
vector<int> lef(n), rig(n), same(n);
stack<int> stk;
for(int i = 0; i < n; i++) {
while(stk.size() && a[stk.top()] <= a[i]) {
if(a[stk.top()] == a[i]) same[i] = same[stk.top()] + 1;
stk.pop();
}
lef[i] = stk.size() ? stk.top() : -1;
stk.push(i);
}
stack<int>().swap(stk); //清空
stk.push(n);
for(int i = n-1; i >= 0; i--) {
while(stk.size() && a[stk.top()] <= a[i]) stk.pop();
rig[i] = stk.size() ? stk.top() : -1;
stk.push(i);
}
ll ans = 0; for(int i = 1; i < n; i++)
ans += (lef[i] != -1) + (rig[i] != -1)
- (lef[i] == 0 && rig[i] == n) + same[i]; //注意0与n是同一个位置
cout << ans << '\n';
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通