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\n",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 */

猜你喜欢

转载自www.cnblogs.com/ZERO-/p/10525748.html
今日推荐