zoukankan      html  css  js  c++  java
  • 跳蚤(线段树)

    跳蚤

    题目描述

    NiroBC 姐姐奴役了一群跳蚤,并随时把它们丢到一台图灵机的纸带上。
    一开始,纸带上没有跳蚤,每一个时刻,NiroBC 姐姐可能做以下三个操作之一:

    1. 在位置x 放置一只每次向右(坐标增大方向)跳t 格的跳蚤。
    2. 命令所有跳蚤向右跳跃一次,跳跃的距离为各自的t。
    3. 给定区间[l,r],求该区间内跳蚤的个数。

    输入

    第一行一个正整数Q,表示操作个数。
    接下来Q 行,这Q 行中的第i 行含有若干个整数,描述第i 个操作。
    (1) 若第一个整数为1,则紧跟两个整数xi 和ti,表示在xi 的位置放置一只每次向右跳跃ti 格的跳蚤。
    (2) 若第一个整数为2,则命令所有跳蚤向右跳跃一次。
    (3) 若第一个整数为3,则紧跟两个整数li 和ri,你需要输出此时区间[li, ri]中跳蚤的数量。

    输出

    对于每一个3 号操作,输出一行一个整数,表示该询问的答案。

    样例输入

    10
    1 4 1
    1 2 2
    3 3 5
    2 3
    3 5
    2 3
    3 5
    3 6 6
    1 5 1
    3 3 5

    样例输出

    1
    2
    0
    2
    1

    思路:

    (B=200),对于(tleq B)的跳蚤,直接建(B)颗线段树,将(t)相同的跳蚤放在一起。
    对于(t>B)的跳蚤,最多跳(1e5/200)次就不会在被记录到,我们暴力模拟,并用树状数组记录下它们的位置。
    另外,设(C)为到(i)为止的跳跃次数,对于所有(t)相同的跳蚤来说,每次跳跃并不改变其相对位置,且其相对位置只与插入时间有关。
    所以我们每次只需把跳蚤插入到(x-C*t)的位置即可。

    code:

    \#pragma GCC optimize(2)
    \#pragma GCC optimize(3, "Ofast", "inline")
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    const int N=1e6+5;
    const ll mod=100000007;
    const double eps=1e-5;
    const double pi=acos(-1);
     
    #define ls p<<1
    #define rs p<<1|1
    int c[N],tl,rt[N],n;
    int C;
    struct node
    {
        int l,r;
        int dat;
    }a[N];
    pii q[N];
    void add(int x,int d)
    {
        for(int i=x;i<=100000;i+=i&-i)
            c[i]+=d;
    }
    int ask(int x)
    {
        int ans=0;
        for(int i=x;i;i-=i&-i) ans+=c[i];
        return ans;
    }
    void build(int &p,int l,int r,int x)
    {
        if(!p) p=++n;
        if(l==r)
        {
            a[p].dat++;
            return;
        }
        int mid=l+r>>1;
        if(x<=mid) build(a[p].l,l,mid,x);
        else build(a[p].r,mid+1,r,x);
        a[p].dat=a[a[p].l].dat+a[a[p].r].dat;
    }
    int query(int p,int l,int r,int x,int y)
    {
        if(!p) return 0;
        if(l>=x&&r<=y) return a[p].dat;
        int mid=l+r>>1;
        int ans=0;
        if(x<=mid) ans+=query(a[p].l,l,mid,x,y);
        if(y>mid) ans+=query(a[p].r,mid+1,r,x,y);
        return ans;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
        ios::sync_with_stdio(false);
        cin.tie(0);
        int _;
        cin>>_;
        while(_--)
        {
            int op;
            cin>>op;
            if(op==1)
            {
                int x,t;
                cin>>x>>t;
                if(t>200)
                {
                    add(x,1);
                    q[++tl]={x,t};
                }
                else   build(rt[t],-t*100000,100000,x-C*t);
            }
            if(op==2)
            {
                C++;
                int cnt=0;
                for(int i=1;i<=tl;i++)
                {
                    add(q[i].first,-1);
                    if(q[i].first+q[i].second<=100000)
                        q[++cnt]={q[i].first+q[i].second,q[i].second};
                }
                tl=cnt;
                for(int i=1;i<=cnt;i++) add(q[i].first,1);
            }
            if(op==3)
            {
                int l,r;
                cin>>l>>r;
                int ans=ask(r)-ask(l-1);
                for(int i=1;i<=200;i++)
                    ans+=query(rt[i],-i*100000,100000,l-C*i,r-C*i);
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    第二阶段~JS中的各种循环语句
    项目一~达人美食图册详情
    项目一~达人行程
    项目一~美食达人图册
    项目一~机票2
    项目一~达人首页
    项目一~Hotel5
    pythonday02基础与运算符
    pythonday01计算机初步认识
    第六章 百度Apollo ROS介绍(2)
  • 原文地址:https://www.cnblogs.com/Suiyue-Li/p/12627183.html
Copyright © 2011-2022 走看看