整体二分 wa 25分的另一种可能
查看原帖
整体二分 wa 25分的另一种可能
105090
wyl_AC楼主2024/7/27 21:03
#include<bits/stdc++.h>
#define N 100005
#define M 100005
#define eps 1e-8
#define K 10
#define T 30001
#define lowbit(x) (x&(-x))
#define i64 long long
#define ui64 unsigned long long
#define i128 __int128
#define lc(x) t[x].ch[0]
#define rc(x) t[x].ch[1]
#define fa(x) t[x].f
#define complex std::complex<double>
#define Mod 1000000007
const i64 INF = 1000000000000000000ll;
struct tree{
    int l,r;
    i64 tot,sum;
}t[N << 3];
void build(int k,int l,int r){
    t[k].l = l,t[k].r = r;
    if(l == r)
        return ;
    int mid = l + r >> 1;
    build(k << 1,l,mid);
    build(k << 1 | 1,mid + 1,r);
    return ;
}
void push_up(int k){
    t[k].sum = t[k << 1].sum + t[k << 1 | 1].sum;
    t[k].tot = t[k << 1].tot + t[k << 1 | 1].tot;
    return ;
}
void add(int k,int p,i64 x){
    if(t[k].l == t[k].r){
        t[k].tot += x;
        t[k].sum = t[k].tot * t[k].l;
        return ;
    }
    int mid = t[k].l + t[k].r >> 1;
    if(p <= mid)
        add(k << 1,p,x);
    else
        add(k << 1 | 1,p,x);
    push_up(k);
    return ;
}
i64 query(int k,i64 L){
    if(t[k].l == t[k].r){
        return L * t[k].l;
    }
    if(t[k << 1].tot >= L)
        return query(k << 1,L);
    else
        return t[k << 1].sum + query(k << 1 | 1,L - t[k << 1].tot);
}
struct node{
    i64 g,L,l,p,d,id;
    bool opt;
}q[N + M],q1[N + M],q2[N + M];
int n,m;
i64 ans[M];
void DC(int l,int r,i64 L,i64 R){
    if(l > r)
        return ;
    if(L == R){
        for(int i = l; i <= r; i++)
            if(!q[i].opt)
                add(1,q[i].p,q[i].l);
            else{
                if(t[1].tot < q[i].L)
                    ans[q[i].id] = 1;
                else{
                    i64 s = query(1,q[i].L);
                    if(s > q[i].g)
                        ans[q[i].id] = -1;
                    else
                        ans[q[i].id] = L;
                }
            }
        for(int i = l; i <= r; i++)
            if(!q[i].opt)
                add(1,q[i].p,-q[i].l);
        return ;
    }
    i64 mid = L + R >> 1;
    int p1 = 0,p2 = 0;
    for(int i = l; i <= r; i++)
        if(!q[i].opt){
            if(q[i].d > mid){
                add(1,q[i].p,q[i].l);
                q2[++p2] = q[i];
            }
            else
                q1[++p1] = q[i];
        }else{
            if(t[1].tot < q[i].L)
                q1[++p1] = q[i];
            else{
                i64 s = query(1,q[i].L);
                if(s > q[i].g)
                    q1[++p1] = q[i];
                else
                    q2[++p2] = q[i];
            }
        }
    for(int i = 1; i <= p2; i++)
        if(!q2[i].opt)
            add(1,q2[i].p,-q2[i].l);
    int p = l;
    for(int i = 1; i <= p1; i++)
        q[p++] = q1[i];
    for(int i = 1; i <= p2; i++)
        q[p++] = q2[i];
    DC(l + p1,r,mid + 1,R);
    for(int i = l + p1; i <= r; i++)
        if(!q[i].opt)
            add(1,q[i].p,q[i].l);
    DC(l,l + p1 - 1,L,mid);
    for(int i = l + p1; i <= r; i++)
        if(!q[i].opt)
            add(1,q[i].p,-q[i].l);
}
void solve(){
    std::cin >> n >> m;
    i64 L = INF,R = 0;
    build(1,1,N - 5);
    for(int i = 1; i <= n; i++){
        std::cin >> q[i].d >> q[i].p >> q[i].l;
        R = std::max(q[i].d,R);
        L = std::min(q[i].d,L);
    }
    for(int i = 1; i <= m; i++){
        std::cin >> q[i + n].g >> q[i + n].L;
        q[i + n].id = i; 
        q[i + n].opt = 1;
    }
    DC(1,n + m,L,R);
    for(int i = 1; i <= m; i++)
        std::cout << ans[i] << '\n';
    return ;
}
signed main(){
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
	std::srand((unsigned)std::time(NULL));
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
    solve();
	return 0;
} 

分治最后没有清零,导致重复加入

2024/7/27 21:03
加载中...