蒟蒻的疑惑(整体二分),已AC,但有些问题不懂
查看原帖
蒟蒻的疑惑(整体二分),已AC,但有些问题不懂
277793
5_Lei楼主2022/8/1 11:54
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 5e4+50;

#define ls rt<<1
#define rs rt<<1|1

ll R()
{
    ll x = 0,f = 1;
    char c = getchar();
    while(c>'9' || c<'0')
    {
        if(c=='-')f=-1;
        c = getchar();
    }
    while(c>='0' && c<='9')
    {
        x = (x<<1)+(x<<3)+(c^48);
        c = getchar();
    }
    return x*f;
}

struct OPT{ ll l,r,c,id,opt;}q[maxn],q1[maxn],q2[maxn];

struct Tree{ll sum,la;}t[maxn<<2];

ll n,m,mx,ans[maxn],a[maxn];

void pushup(ll rt){ t[rt].sum = t[ls].sum + t[rs].sum; }

void pushdown(ll rt,ll l,ll r)
{
    ll la = t[rt].la;
    if(la)
    {
        ll mid = (l+r)>>1;
        t[rt].la = 0;
        t[rs].la  += la;
        t[ls].la += la;
        t[ls].sum += (mid-l+1)*la;
        t[rs].sum += (r-mid)*la;
    }
}

void update(ll rt,ll l,ll r,ll L,ll R,ll d)
{
    if(L <= l && r <= R)
    {
        t[rt].sum += (r-l+1)*d;
        t[rt].la += d;
        return;
    }
    pushdown(rt,l,r);
    ll mid = (l+r)>>1;
    if(mid < R)update(rs,mid+1,r,L,R,d);
    if(mid >= L)update(ls,l,mid,L,R,d);
    pushup(rt);
}

ll query(ll rt,ll l,ll r,ll L,ll R)
{
    if(L <= l && r <= R)return t[rt].sum;
    pushdown(rt,l,r);
    ll mid = (l+r)>>1,ans = 0;
    if(mid < R)ans += query(rs,mid+1,r,L,R);
    if(mid >= L)ans += query(ls,l,mid,L,R);
    return ans;
}

void solve(ll l,ll r,ll L,ll R)
{
    if(l==r)
    {
        for(int i = L ; i <= R ; i++)if(q[i].opt==2)ans[q[i].id] = l;
        return;
    }
    ll mid = (l+r)>>1,cnt1 = 0,cnt2 = 0;
    for(int i = L ; i <= R; i++)
    {
        if(q[i].opt == 1)
        {
            if(q[i].c > mid)update(1,1,n,q[i].l,q[i].r,1),q1[++cnt1] = q[i];
            else q2[++cnt2] = q[i];
        }
        else
        {
            ll t = query(1,1,n,q[i].l,q[i].r);
            if(q[i].c <= t)q1[++cnt1] = q[i];
            else q[i].c-=t,q2[++cnt2] = q[i];
        }
    }
    for(int i = 1 ; i <= cnt1 ; i++)if(q1[i].opt == 1)update(1,1,n,q1[i].l,q1[i].r,-1);
    for(int i = 1 ; i <= cnt1 ; i++)q[L+i-1] = q1[i];
    for(int i = 1 ; i <= cnt2 ; i++)q[L+cnt1+i-1] = q2[i];
    solve(mid+1,r,L,L+cnt1-1),solve(l,mid,L+cnt1,R);
}

bool cmp(OPT a,OPT b){return a.id < b.id;}

void Lei()
{
    n = R(),m = R();
    for(int i = 1 ; i <= m ; i++)
    {   
        ll opt = R(),l = R(),r = R(),c = R();
        q[i] = (OPT){l,r,c,i,opt};
        mx = max(mx,c);
    }
    solve(0,n+1,1,m);
    sort(q+1,q+m+1,cmp);
    for(int i = 1 ; i <= m ; i++)if(q[i].opt==2)printf("%lld\n",ans[q[i].id]);
}

int main()
{
    Lei();
    return 0;
}

一:据说这道题有负数,我没有判就过了

二:题面中说操作2中c<=263c<= 2^{63},可是集合数量不才到n吗?会输出什么呢?

求神犇答疑

2022/8/1 11:54
加载中...