zoukankan      html  css  js  c++  java
  • LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)

    内存限制:256 MiB时间限制:500 ms标准输入输出
    题目类型:传统评测方式:文本比较
    上传者: hzwer

    题目描述

    给出一个长为 nn 的数列,以及 nn 个操作,操作涉及单点插入,单点询问,数据随机生成。

    输入格式

    第一行输入一个数字 nn。

    第二行输入 nn 个数字,第 ii 个数字为 a_iai,以空格隔开。

    接下来输入 nn 行询问,每行输入四个数字 mathrm{opt}opt、ll、rr、cc,以空格隔开。

    若 mathrm{opt} = 0opt=0,表示在第 ll 个数字前插入数字 rr(cc 忽略)。

    若 mathrm{opt} = 1opt=1,表示询问 a_rar 的值(ll 和 cc 忽略)。

    输出格式

    对于每次询问,输出一行一个数字表示答案。

    样例

    样例输入

    4
    1 2 2 3
    0 1 3 1
    1 1 4 4
    0 1 2 2
    1 1 2 4

    样例输出

    2
    3

    数据范围与提示

    对于 100\%100% 的数据,1 leq n leq 100000, -2^{31} leq mathrm{others}1n100000,231others、mathrm{ans} leq 2^{31}-1ans2311。

    代码:

      1 //#6282. 数列分块入门 6-单点插入,单点查询,数据随机生成
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 typedef long long ll;
      5 const int maxn=1e5+10;
      6 
      7 int n,m;
      8 int a[maxn*5],b[maxn],tag[maxn],pos[maxn];
      9 vector<int> vec[maxn];
     10 
     11 void rebuild()
     12 {
     13     memset(a,0,sizeof(a));
     14     int h=0;
     15     for(int i=1;i<=m+1;i++){
     16         for(auto it:vec[i]){
     17             a[++h]=it;
     18         }
     19         vec[i].clear();
     20     }
     21     m=sqrt(h);
     22     for(int i=1;i<=h;i++)
     23         pos[i]=(i-1)/m+1;
     24     for(int i=1;i<=h;i++){
     25         vec[pos[i]].push_back(a[i]);
     26     }
     27 }
     28 
     29 pair<int,int> find_pos(int r)
     30 {
     31     int i=1,cnt;
     32     while(1){
     33         if(r>vec[i].size()){
     34             r-=vec[i].size();
     35             i++;
     36         }
     37         else{
     38             cnt=i;
     39             break;
     40         }
     41     }
     42     return make_pair(cnt,r);
     43 }
     44 
     45 void update(int l,int r)
     46 {
     47     pair<int,int> pr=find_pos(l);
     48     vec[pr.first].insert(vec[pr.first].begin()+pr.second-1,r);
     49     if(vec[pr.first].size()>3*m) rebuild();
     50 }
     51 
     52 int query(int r)
     53 {
     54     pair<int,int> pr=find_pos(r);
     55     return vec[pr.first][pr.second-1];
     56 }
     57 
     58 int main()
     59 {
     60     scanf("%d",&n);
     61     m=sqrt(n);
     62     for(int i=1;i<=n;i++){
     63         scanf("%d",&a[i]);
     64         pos[i]=(i-1)/m+1;
     65     }
     66     for(int i=1;i<=n;i++){
     67         vec[pos[i]].push_back(a[i]);
     68     }
     69     for(int i=1;i<=n;i++){
     70         int op,l,r,c;
     71         scanf("%d%d%d%d",&op,&l,&r,&c);
     72         if(op==0){
     73             update(l,r);
     74         }
     75         else{
     76             printf("%d
    ",query(r));
     77         }
     78     }
     79     return 0;
     80 }
     81 
     82 
     83 /*
     84 10
     85 1 3 4 2 5 7 11 3 5 1
     86 0 1 5 1
     87 1 1 7 2
     88 0 3 9 1
     89 1 4 8 7
     90 1 1 10 6
     91 1 3 5 3
     92 1 5 9 7
     93 1 6 12 6
     94 1 2 7 4
     95 1 3 4 5
     96 
     97 7
     98 7
     99 3
    100 4
    101 11
    102 1
    103 5
    104 3
    105 */
  • 相关阅读:
    第一次c++团队合作项目第三篇随笔
    第一次c++团队合作项目第二篇随笔
    第一次c++团队合作作业期间第一篇随笔
    电梯调度程序
    给我留下深刻印象的三位老师
    一个带有富文本功能的记事本
    我也忘了第几次团队作业
    关于复数输入输出的一点见解
    c++团队作业工作笔记
    又要开始新的征程了hhh(这次内容比较感兴趣)
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10525748.html
Copyright © 2011-2022 走看看