1 条题解

  • 0
    @ 2026-5-13 8:31:11

    闲话

    巨佬

    https://www.luogu.com.cn/user/1359984
    改题解,我优化了亿点点... 求管理大大过审吧。

    思路

    这题一看就是贪心,购买时间越晚的物品越早卖,否则时间晚买的物品可以把时间早买的给换掉,并对左端点更靠右的物品有贡献

    那么对每种类型的物品开一个栈,栈内为还未卖出的物品节点,每次遇到一个可以卖出的节点就弹栈。设栈顶元素为 LL,卖出节点为 RR,则询问 [li,ri][l_i,r_i] 的答案为满足 [L,R][li,ri][L,R] \subseteq [li,ri] 的二元组 (L,R)(L,R) 的个数。

    时间复杂度: O(logn)O(\log n)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        int x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
        return x;
    }
    int stk[10],tp;
    inline void write(int x)
    {
        if(!x) return puts("0"),void();
        tp=0;
        while(x) stk[++tp]=x%10,x/=10;
        while(tp) putchar(stk[tp--]^48);
        putchar('\n');
    }
    const int N=5e5+10;
    struct ok{
        int l,id;
    };
    int n,q,a[N],c[N],Tr[N],ans[N];
    vector<int>Q[N];
    vector<ok>ask[N];
    void add(int x) {for(;x;x-=(x&-x)) ++Tr[x];}
    int query(int x,int res=0) {for(;x<=n;x+=(x&-x)) res+=Tr[x];return res;}
    int main()
    {
        n=read(),q=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1,x;i<=n;i++)
        {
            x=read();
            if(a[i]&&!Q[x].empty()) c[i]=Q[x].back(),Q[x].pop_back();
            if(!a[i]) Q[x].push_back(i);
        }
        for(int i=1,l,r;i<=q;i++)
            l=read(),r=read(),ask[r].push_back((ok){l,i});
        for(int i=1;i<=n;i++)
        {
            add(c[i]);
            for(ok x:ask[i]) ans[x.id]=query(x.l);
        }
        for(int i=1;i<=q;i++) write(ans[i]);
        return n&0;
    }
    • 1

    信息

    ID
    7434
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者