省选/NOI-难度的题目,AI秒破解??
2025-05-25 20:38:10
发布于:浙江
34阅读
0回复
0点赞
以下为AI破解的证据(43秒就破解了??):
AC代码(反正我是看不懂):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// Segment Tree with range-add and range-max
struct SegTree {
int n;
struct Node {
ll mx;
ll add;
};
vector<Node> st;
SegTree(int _n=0): n(_n) {
st.assign(4*n+4, {LLONG_MIN, 0});
}
void build(int p, int l, int r, const vector<ll> &init) {
if (l == r) {
st[p].mx = init[l];
st[p].add = 0;
return;
}
int m = (l+r)>>1;
build(p<<1, l, m, init);
build(p<<1|1, m+1, r, init);
st[p].mx = max(st[p<<1].mx, st[p<<1|1].mx);
st[p].add = 0;
}
void apply(int p, ll v) {
st[p].mx += v;
st[p].add += v;
}
void push(int p) {
if (st[p].add != 0) {
apply(p<<1, st[p].add);
apply(p<<1|1, st[p].add);
st[p].add = 0;
}
}
void update(int p, int l, int r, int i, int j, ll v) {
if (i > r || j < l) return;
if (i <= l && r <= j) {
apply(p, v);
return;
}
push(p);
int m = (l+r)>>1;
update(p<<1, l, m, i, j, v);
update(p<<1|1, m+1, r, i, j, v);
st[p].mx = max(st[p<<1].mx, st[p<<1|1].mx);
}
ll query_max() const {
return st[1].mx;
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, p, q;
cin >> n >> m >> p >> q;
vector<pair<int,int>> dishes(m);
vector<int> all_t, all_c;
all_t.reserve(m);
all_c.reserve(m);
for(int i = 0; i < m; i++){
int t, c;
cin >> t >> c;
dishes[i] = {t, c};
all_t.push_back(t);
all_c.push_back(c);
}
vector<int> picky(p);
for(int i = 0; i < p; i++){
cin >> picky[i];
}
vector<int> poor(q);
for(int i = 0; i < q; i++){
cin >> poor[i];
}
int r = n - p - q; // free people
// Sort picky thresholds and poor thresholds
sort(picky.begin(), picky.end());
sort(poor.begin(), poor.end());
// Check that every dish has at least one eligible person
for(int i = 0; i < m; i++){
int t = dishes[i].first;
int c = dishes[i].second;
// count picky with a_i <= t
int cnt_picky = int(upper_bound(picky.begin(), picky.end(), t) - picky.begin());
// count poor with b_j >= c
int cnt_poor = int(poor.end() - lower_bound(poor.begin(), poor.end(), c));
if (cnt_picky + cnt_poor + r == 0) {
cout << -1 << "\n";
return 0;
}
}
// Coordinate compress t and c among dishes
sort(all_t.begin(), all_t.end());
all_t.erase(unique(all_t.begin(), all_t.end()), all_t.end());
sort(all_c.begin(), all_c.end());
all_c.erase(unique(all_c.begin(), all_c.end()), all_c.end());
int Tt = (int)all_t.size();
int Tc = (int)all_c.size();
// Map each dish to t_idx (1..Tt) and c_idx (1..Tc)
vector<int> dish_tidx(m), dish_cidx(m);
for(int i = 0; i < m; i++){
int t = dishes[i].first;
int c = dishes[i].second;
int ti = int(lower_bound(all_t.begin(), all_t.end(), t) - all_t.begin()) + 1;
int ci = int(lower_bound(all_c.begin(), all_c.end(), c) - all_c.begin()) + 1;
dish_tidx[i] = ti;
dish_cidx[i] = ci;
}
// For each t_idx x, collect j_rev indices of dishes with that t
// First, compute j_rev = C - c_idx + 1
vector<vector<int>> by_tidx(Tt+1);
by_tidx.assign(Tt+1, vector<int>());
for(int i = 0; i < m; i++){
int ti = dish_tidx[i];
int ci = dish_cidx[i];
int j_rev = Tc - ci + 1;
by_tidx[ti].push_back(j_rev);
}
// Precompute P[x]: count of picky with threshold <= all_t[x-1]
vector<int> P(Tt+1, 0);
int ptr = 0;
for(int x = 1; x <= Tt; x++){
int tx = all_t[x-1];
while(ptr < p && picky[ptr] <= tx) ptr++;
P[x] = ptr;
}
// Precompute Q[j]: for each c index j (1..Tc), count of poor with threshold >= all_c[j-1]
vector<int> Q(Tc+1, 0);
for(int j = 1; j <= Tc; j++){
int cj = all_c[j-1];
int cnt = int(poor.end() - lower_bound(poor.begin(), poor.end(), cj));
Q[j] = cnt;
}
// Build Q_rev
vector<int> Qrev(Tc+2, 0);
for(int j_rev = 1; j_rev <= Tc; j_rev++){
int j = Tc - j_rev + 1;
Qrev[j_rev] = Q[j];
}
// Binary search on T
ll low = (m + n - 1) / n; // ceil(m/n)
ll high = m;
ll ans = -1;
// Prepare a vector for initial leaf values (size Tc), to be overwritten each T
vector<ll> init(Tc+1, 0);
while(low <= high){
ll mid = (low + high) >> 1;
// Build initial array: init[j_rev] = -mid * Qrev[j_rev]
for(int j_rev = 1; j_rev <= Tc; j_rev++){
init[j_rev] = -mid * (ll)Qrev[j_rev];
}
// Build segment tree
SegTree st(Tc);
st.build(1, 1, Tc, init);
bool ok = true;
// Process t_idx from 1..Tt
for(int x = 1; x <= Tt; x++){
// For each dish at this t_idx, we have updates at its j_rev
for(int j_rev : by_tidx[x]){
// Add 1 to range [j_rev..Tc]
st.update(1, 1, Tc, j_rev, Tc, 1LL);
}
// Compute base = mid * (P[x] + r)
ll base = mid * (ll)(P[x] + r);
ll Mx = st.query_max();
if (Mx > base) {
ok = false;
break;
}
}
if (ok) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
if (ans < 0) cout << -1 << "\n";
else cout << ans << "\n";
return 0;
}
全部评论 2
原来你也有不会的题
2025-05-27 来自 江苏
0怎么,你会?
2025-05-29 来自 浙江
0包不会的
2025-05-29 来自 江苏
0
顶!
2025-05-25 来自 浙江
0
有帮助,赞一个