• #6282. 数列分块入门 6(单点插入,单点询问)


    题目链接:https://loj.ac/problem/6282

    题目大意:中文题目

    具体思路:用vector存,每一次查询的时候,从头开始,逐段逐段的减,更新的时候,也是从头开始。插入:q.insert(q.begin()+(长度-1),val),如果一个段里面存的值过多的话,可以考虑重新建图。

    AC代码:

     1 #include<iostream>
     2 #include<cmath>
     3 #include<stdio.h>
     4 #include<algorithm>
     5 #include<map>
     6 #include<vector>
     7 using namespace std;
     8 # define ll long long
     9 const int maxn = 2e5+100;
    10 int a[maxn],n,block,tot,maxpos;
    11 vector<int>q[maxn];
    12 void rebuild(){
    13 int cnt=0;
    14 for(int i=1;i<=maxpos;i++){
    15 for(int j=0;j<q[i].size();j++){
    16 a[++cnt]=q[i][j];
    17 }
    18 q[i].clear();
    19 }
    20 for(int i=1;i<=cnt;i++){
    21 q[(i-1)/block+1].push_back(a[i]);
    22 }
    23 maxpos=(cnt-1)/block+1;
    24 }
    25 pair<int,int>query(int pos){
    26 int cnt=1;
    27 while(pos>q[cnt].size()){
    28 pos-=q[cnt].size();
    29 cnt++;
    30 }
    31 return make_pair(cnt,pos-1);
    32 }
    33 void add(int pos,int val){
    34 pair<int,int>w=query(pos);
    35 q[w.first].insert(q[w.first].begin()+w.second,val);
    36 if(q[w.first].size()>10*block)rebuild();
    37 }
    38 int ask(int pos){
    39 pair<int,int>w=query(pos);
    40 return q[w.first][w.second];
    41 }
    42 int main(){
    43 scanf("%d",&n);
    44 block=(int)sqrt(n);
    45 for(int i=1;i<=n;i++){
    46 scanf("%d",&a[i]);
    47 q[(i-1)/block+1].push_back(a[i]);
    48 }
    49 maxpos=(n-1)/block+1;
    50 int q=n;
    51 int op,st,ed,val;
    52 while(q--){
    53 scanf("%d %d %d %d",&op,&st,&ed,&val);
    54 if(op==0){
    55 add(st,ed);
    56 }
    57 else if(op==1){
    58 printf("%d
    ",ask(ed));
    59 }
    60 }
    61 return 0;
    62 }
  • 相关阅读:
    sdnu 1513 字符串翻转
    hdu-1559 最大子矩阵(二维树状数组模板题)
    hdu-1556 树状数组
    1049.饭盒
    1092.校门外的树
    1012.区间合并
    1054.数独
    1175.开心的金明 01背包
    空格(Space)的ASCII码值是:32
    js为lable和div赋值
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10471766.html
Copyright © 2020-2023  润新知