社区讨论
截止8.1悬赏5元求卡常,不WA只TLE
P8349 [SDOI/SXOI2022] 整数序列参与者 4已保存回复 14
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 14 条
- 当前快照
- 1 份
- 快照标识符
- @mdi2xj0s
- 此快照首次捕获于
- 2025/07/25 08:24 8 个月前
- 此快照最后确认于
- 2025/11/04 06:29 4 个月前
代码算小清新的。
各位大佬帮我这个蒟蒻看看,这份代码目前只能获得和暴力同样的分数。
我非常怀疑,到底是我代码复杂度有问题还是单纯卡常?
应该没有 WA 的问题,本地拍了 组大数据无误,但是速度比较慢,一组大概 的样子。
代码中 用来记录小颜色配大颜色的时候,跳过没有用的大颜色的位置,这些断点的位置。剩余应该简单。
CPP#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 300010, INF = 1e18;
int n, a[N], m, B;
int s[N], val[N], sv[N];
vector<int> cnt[N];
set<int> ps[N];
int g[1000][1000];
int buck[N * 2], mark[N], tong[N];
inline int bf(int x, int y)
{
vector<int> v;
int px = 0, py = 0;
while (px <= (int)cnt[x].size() - 1 || py <= (int)cnt[y].size() - 1)
if (px == (int)cnt[x].size()) v.push_back(cnt[y][py ++ ]);
else if (py == (int)cnt[y].size()) v.push_back(cnt[x][px ++ ]);
else if (cnt[x][px] < cnt[y][py]) v.push_back(cnt[x][px ++ ]);
else v.push_back(cnt[y][py ++ ]);
int last = 0, res = -1e18;
vector<int> us;
buck[0 + N] = 0;
for (int i = v[0] - 1, cur = 0; i >= 0; i -- )
cur += a[i], buck[0 + N] = min(buck[0 + N], cur);
int tmp = buck[0 + N];
for (auto i : v)
{
s[i] = s[last] + (a[i] == x ? 1 : -1);
sv[i] = sv[last] + val[i];
last = i;
if (buck[s[i] + N] != -1) res = max(res, sv[i] - sv[buck[s[i] + N]]);
if (buck[s[i] + N] == -1) us.emplace_back(s[i] + N), buck[s[i] + N] = i;
else if (sv[buck[s[i] + N]] > sv[i]) buck[s[i] + N] = i;
if (mark[i])
{
for (auto i : us) buck[i] = -1;
us.clear();
buck[0 + N] = tmp;
last = 0;
}
}
for (auto i : us) buck[i] = -1;
return res;
}
signed main()
{
memset(buck, -1, sizeof buck);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
cin >> a[i];
cnt[a[i]].emplace_back(i);
}
B = sqrt(n);
vector<int> v;
for (int i = 1; i <= n; i ++ )
if ((int)cnt[i].size() > B) v.push_back(i), tong[i] = v.size();
for (auto i : v)
for (auto j : cnt[i])
ps[i].insert(j);
for (int i = 1; i <= n; i ++ ) cin >> val[i];
for (int i = 0; i < v.size(); i ++ )
for (int j = i + 1; j < v.size(); j ++ )
g[tong[v[j]]][tong[v[i]]] = g[tong[v[i]]][tong[v[j]]] = bf(v[i], v[j]); //return 0;
while (m -- )
{
int x, y;
cin >> x >> y;
if ((int)cnt[x].size() <= B && (int)cnt[y].size() <= B) cout << bf(x, y) << "\n";
else if ((int)cnt[x].size() > B && (int)cnt[y].size() > B) cout << g[tong[x]][tong[y]] << "\n";
else
{
if (cnt[x].size() > cnt[y].size()) swap(x, y);
vector<int> er, us;
for (auto i : cnt[x])
{
ps[y].insert(i);
auto it = ps[y].find(i);
if (it != ps[y].begin())
{
auto it2 = it;
it2 -- ;
er.push_back(*it2);
ps[y].erase(*it2);
}
auto it2 = it; it2 ++ ;
if (it2 != ps[y].end())
{
er.push_back(*it2);
ps[y].erase(*it2);
}
ps[y].erase(i);
}
for (auto i : er) ps[y].insert(i);
sort(er.begin(), er.end());
for (int i = 0; i < (int)er.size() - 1; i ++ )
{
auto id = ps[y].find(er[i]);
id ++ ;
if (er[i + 1] != (*id)) mark[er[i]] = 1, us.push_back(er[i]);
}
swap(er, cnt[y]);
cout << bf(x, y) << "\n";
swap(er, cnt[y]);
for (auto i : us) mark[i] = 0;
}
}
return 0;
}
回复
共 14 条回复,欢迎继续交流。
正在加载回复...