CF1905E One-X 题解
先考虑
非常显然地,按照线段树建树,枚举每个点作为 LCA 的答案。假设当前节点
上述的朴素做法复杂度为
但现在问题是,上文的贡献中还有
现在的问题是,为什么是关于
令
首先,
考虑
进一步,由于左右儿子的
所以
其中
发现这个式子关于
具体地:
使用 map
记忆化即可。复杂度
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const long long MOD = 998244353ll;
using ll = long long;
int t;
ll n;
map<ll, pair<ll, ll>> mp;
ll qpow(ll a, ll b)
{
ll res = 1ll, base = a;
while (b)
{
if (b & 1ll) res = res * base % MOD;
base = base * base % MOD;
b >>= 1ll;
}
return res;
}
pair<ll, ll> query(ll u, ll len)
{
if (mp.count(len)) return mp[len];
if (len == 1) return (mp[len] = make_pair(1ll, 0ll));
if (len == 0) return (mp[len] = make_pair(0ll, 0ll));
ll x = (len + 1) / 2ll, y = len / 2ll;
auto lft = query(u << 1ll, x), rit = query(u << 1ll | 1ll, y);
auto res = make_pair(((2ll * lft.first % MOD + 2ll * rit.first % MOD) % MOD + ((qpow(2ll, x) - 1) * (qpow(2ll, y) - 1) % MOD)) % MOD, (lft.second + rit.second + rit.first) % MOD);
return mp[len] = res;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
cin >> t;
while (t--)
{
cin >> n;
mp.clear();
auto g = query(1, n);
cout << (g.first + g.second) % MOD << "\n";
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现