[arbre] Segment puces

Titre description

soeur NiroBC asservit un groupe de puces, et ne hésitez pas à les jeter sur la bande d'une machine de Turing.
Dans un premier temps , pas de puces sur la bande, à chaque instant, la sœur NiroBC peut faire l' une des trois choses:

  1. Chacun d'eux est placé à une position x vers la droite (sens croissant de coordonnées) t saut grille des puces.
  2. Exigé des puces sautent vers la droite une fois, la distance de saut pour leur t respective.
  3. Compte tenu de l'intervalle [l, r], trouver le nombre de puces dans l'intervalle.

entrée

La première ligne d'un Q entier positif, représente le nombre d'opérations.
Suivant rangée Q, dans laquelle Q i-ième ligne de rangée comprenant une pluralité de nombres entiers, des opérations i-décrit.
(1) Si le premier nombre entier est égal à 1, puis suivie de deux entiers xi et ti, représentent chacun un saut à la grille de ti bon endroit positions xi des puces.
(2) Si le premier entier est 2, a ordonné à tous les puces sautent moment.
(3) Si le premier entier 3, puis a suivi deux entiers li et ri, le nombre de la production dont vous avez besoin intervalle [li, RI] dans le cas des puces.

exportation

3, pour chaque opération, la ligne de sortie d'un nombre entier, représente la réponse à cette demande.

problème solution

Pour l' étape ① a grandi dans les puces 200 (longueur de la foulée), jusqu'à 500 fois va sauter hors des limites, de sorte que la simulation directe, la position de puces d'entretien avec arbre Fenwick. La complexité de O (log * 500 * 1E5 (1E5))
② inférieure ou égale à l'étape 200 les puces (petits pas), les puces dans l'étape de classification t, pour chaque t, un arbre de segment à construire, à entretenir les étapes longueur est la position initiale du t puces.
Une opération d'un tel doit être inséré dans une puce de pas x t bits de long, et a été mis en œuvre avant que les durées de fonctionnement 2 fois ( à savoir, sauter), que cette opération peut être équivalent à 1 au début est le mode de réalisation ( à savoir avant toutes les opérations) à insérer xt * fois à une taille de pas de puces t. Cela toutes les étapes de puces t ont un temps de saut d'étape unifiée, et ont fait une position de départ correspondant conversion équivalente.
Dans la demande de recherche [l, r] intervalle lorsque le nombre de puces dans de petits pas, si les opérations ont été mises en œuvre avant 2 fois, l'étape de puces t, la requête correspondant à la position de départ [lt * fois, rt * fois ] le nombre de puces, et en réponse aux statistiques. La complexité O (200 * 1e5 * log ( 1e5))

code

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#define lowbit(x) x&(-x)
using namespace std;
const int n=1e5;

int c[100005];
inline void add(int pos,int val){
  for(int i=pos;i<=n;i+=lowbit(i)){
    c[i]+=val;
  }
}
inline int getsum(int pos){
  int ret=0;
  for(int i=pos;i>0;i-=lowbit(i)){
    ret+=c[i];
  }
  return ret;
}
pair<int,int> P[100005];
int tot=0;

int rt[205];
struct Node{
  int l,r,sum;
}node[3000005];
int ls[3000005],rs[3000005];
int id=0;
inline int newNode(int l,int r){
  node[++id]=Node{l,r,0};
  return id;
}

void addval_to_point(int k,int pos,int val){
  if(node[k].l==node[k].r){
    node[k].sum+=val;
    return;
  }
  int mid=(node[k].l+node[k].r)>>1;
  if(pos<=mid){
    if(!ls[k]) ls[k]=newNode(node[k].l,mid);
    addval_to_point(ls[k],pos,val);
  }
  else{
    if(!rs[k]) rs[k]=newNode(mid+1,node[k].r);
    addval_to_point(rs[k],pos,val);
  }
  node[k].sum=node[ls[k]].sum+node[rs[k]].sum;
}

int ask_interval_sum(int k,int l,int r){
  if(!k) return 0;
  if(l<=node[k].l&&node[k].r<=r) return node[k].sum;
  int mid=(node[k].l+node[k].r)>>1;
  int ret=0;
  if(l<=mid) ret+=ask_interval_sum(ls[k],l,r);
  if(r>mid) ret+=ask_interval_sum(rs[k],l,r);
  return ret;
}

int main()
{
    int q;scanf("%d",&q);
    int times=0;
    while(q--){
        int op;scanf("%d",&op);
        if(op==1){
            int x,t;scanf("%d%d",&x,&t);
            if(t>200){
                P[++tot]=make_pair(x,t);
                add(x,1);
            }
            else{
                int pos=x-t*times;
                if(!rt[t]) rt[t]=newNode(-t*100000,100000);
                addval_to_point(rt[t],pos,1);
            }
        }
        else if(op==2){
            times++;
            int _tot=0;
            for(int i=1;i<=tot;++i){
                int x=P[i].first,t=P[i].second;
                add(x,-1);
                if(x+t<=n){
                    add(x+t,1);
                    P[++_tot]=make_pair(x+t,t);
                }
            }
            tot=_tot;
        }
        else{
            int l,r;scanf("%d%d",&l,&r);
            int ans=getsum(r)-getsum(l-1);
            for(int i=1;i<=200;++i){
                ans+=ask_interval_sum(rt[i],l-i*times,r-i*times);
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}

Je suppose que tu aimes

Origine www.cnblogs.com/lllxq/p/12634464.html
conseillé
Classement