YY模拟:跳蚤(分块)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/79962840

题意:
维护以下三个操作:
1. 在位置x 放置一只每次向右(坐标增大方向)跳t 格的跳蚤。
2. 命令所有跳蚤向右跳跃一次,跳跃的距离为各自的t
3. 给定区间[l;r],求该区间内跳蚤的个数。
Q1e5,1x,ti1e5,1liri1e5

题解:
注意到li,ri有限制,于是可以对t分块,小的用线段树维护,大的单独维护。时间复杂度O(nnlogn)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long LL;
typedef pair <int,int> pii;
typedef tree <pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update> Set;

const int RLEN=1<<18|1;
inline char nc() {
    static char ibuf[RLEN],*ib,*ob;
    (ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ib==ob) ? -1 : *ib++; 
}
inline int rd() {
    char ch=nc(); int i=0,f=1;
    while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
    while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
    return i*f;
}
inline void W(int x) {
    static int buf[50];
    if(!x) {putchar('0'); return;}
    if(x<0) {putchar('-'); x=-x;}
    while(x) {buf[++buf[0]]=x%10; x/=10;}
    while(buf[0]) {putchar(buf[buf[0]--]+'0');}
}
const int N=1e5+50, B=200, INF=0x3f3f3f3f;

int n;
LL tag[B]; list <pii> ls;
struct MySet {
    unordered_map <LL,int> mp;
    Set S;
    inline void insert(LL v) {
        int t=++mp[v];
        S.insert(make_pair(v,t));
    }
    inline void erase(LL v) {
        int t=mp[v]--;
        S.erase(S.find(pii(v,t)));
    }
    inline int ask(LL v) {
        return S.order_of_key(pii(v,INF));
    }
} s[B],s2;

int main() {
    n=rd();
    for(int i=1;i<=n;i++) {
        int op=rd();
        if(op==1) {
            int x=rd(), y=rd();
            if(y>=B) {
                if(x>N) continue;
                s2.insert(x); 
                ls.insert(ls.end(),pii(x,y));
            } else {
                s[y].insert(x-tag[y]);
            }
        } else if(op==2) {
            for(int j=1;j<B;j++) tag[j]+=j;
            for(list <pii> ::iterator it=ls.begin();it!=ls.end();) {
                list <pii> ::iterator now=it++;
                s2.erase(now->first);
                if(now->first+now->second>N) ls.erase(now);
                else now->first+=now->second, s2.insert(now->first);
            }
        } else {
            int l=rd(), r=rd(), ans=0;
            for(int j=1;j<B;j++) ans+=s[j].ask(r-tag[j])-s[j].ask(l-1-tag[j]);
            ans+=s2.ask(r)-s2.ask(l-1);
            W(ans); putchar('\n');
        }
    }
} 
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页