Atcoder abc 221 E - LEQ
原题链接:E - LEQ
思路:
题目要求对于从数组1~n找出所有符合开头数字小于等于结尾数字的子序列,,满足,很显然,我们只需要找到任何一对数对,然后它的贡献是,我们可以两重循环很容易做到,但是很明显数据范围不允许,这时候考虑,将变成,那么答案就是,其中是,对于可以直接用快速幂求解,而对于我们可以直接用树状数组进行维护,这样复杂度就由优化为了,又由于涉及取模,因为除法不能直接取模,所以求的逆元即可。
哦对了,由于使用树状数组,所以先离散化一下。
// Problem: E - LEQ
// Contest: AtCoder - AtCoder Beginner Contest 221
// URL: https://atcoder.jp/contests/abc221/tasks/abc221_e
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
const int N = 3E5 + 10, Mod = 998244353;
LL tr[N];
int a[N], n;
vector<int> alls;
LL lowbit(LL x) {
return x & -x;
}
void modify(int x, LL v) { //从下往上加
for (;x < N; x += lowbit(x)) tr[x] = (tr[x] + v) % Mod;
}
LL query(int x) {
LL res = 0;
for (;x ; x -= lowbit(x)) res = (res + tr[x]) % Mod;
return res;
}
LL qpow(LL a, LL b, LL Mod) {
LL res = 1;
while (b) {
if (b & 1) res = res * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return res;
}
int find(int x) {
return lower_bound(alls.begin(), alls.end(), x) - alls.begin() + 1;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
alls.push_back(a[i]);
}
sort(alls.begin(), alls.end());
alls.erase(unique(alls.begin(), alls.end()), alls.end());
LL res = 0;
for (int i = 1; i <= n; i++) {
int x = find(a[i]);
res = (res + qpow(2, i - 1, Mod) * query(x) % Mod) % Mod;
LL t = qpow(2, i, Mod);
modify(x, qpow(t, Mod - 2, Mod));
}
cout << res << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端