Let's design a data structure A that combines arrays and linked lists as the following:
At the very beginning, an integer array A0 of length L0 is initialized for the user. When the user tries to access the ith element A[i], if 0≤i<L0, then A[i] is just A0[i]. Now our system is supposed to return h0+i×sizeof(int) as the accessed address, where h0 is the initial address of A0, and sizeof(int) is the size of the array element, which is simply int, taking 4 bytes.
In case there is an overflow of the user's access (that is, i≥L0), our system will declare another array A1 of length L1. Now A[i] corresponds to A1[j] (It's your job to figure out the relationship between i and j). If 0≤j<L1, then h1+j×sizeof(int) is returned as the accessed address, where h1 is the initial address of A1.
And if there is yet another overflow of the user's access to A1[j], our system will declare another array A2 of length L2, and so on so forth.
Your job is to implement this data structure and to return the address of any access.
Input Specification:
Each input file contains one test case. For each case, the first line gives 2 positive integers N (≤104) and K (≤103) which are the number of arrays that can be used, and the number of user queries, respectively.
Then N lines follow, each gives 2 positive integers, which are the initial address (≤107) and the length (≤100) of an array, respectively. The numbers are separated by spaces. It is guaranteed that there is no overlap of the spaces occupied by these arrays.
Finally, K indices of the elements queried by users are given in the last line. Each index is an integer in the range [0,220].
Output Specification:
For each query, print in a line the accessed address. If the queried index exceeds the range of all the N arrays, output Illegal Access
instead, and this query must NOT be processed.
Print in the last line the total number of arrays that have been declared for the whole process.
Sample Input:
6 7
2048 5
128 6
4016 10
1024 7
3072 12
9332 10
2 12 25 50 28 8 39
Sample Output:
2056
4020
1040
Illegal Access
3072
140
3116
5
###Hint:
A[2] is just A0[2], so the accessed address is 2048+2×4=2056.
In order to access A[12], declaring A1 is not enough, we need A2 with initial address h2=4016. Since A[12]=A2[1], the accessed address is 4016+1×4=4020.
In order to access A[25], we need A3 with initial address h3=1024. Since A[25]=A3[4], the accessed address is 1024+4×4=1040.
The access of A[50] exceeds the maximum boundary of all the arrays, and hence an illegal access. There is no extra array declared.
In order to access A[28], we need A4 with initial address h4=3072. Since A[28]=A4[0], the accessed address is just 3072.
It is clear to see that A[8]=A1[3] and hence the accessed address is 128+3×4=140; and A[39]=A4[11] so the accessed address is 3072+11×4=3116.
All together there are 5 arrays used for the above queries.
#include<iostream>
using namespace std;
const int N = 10010;
int endadd[N],startadd[N];
bool flag[N];
int n,m;
int main(){
cin>>n>>m;
for(int i = 0;i<n;i++){
int address,cnt;
scanf("%d %d",&address,&cnt);
startadd[i] = address;
if(i==0) endadd[i] = cnt-1;
else endadd[i] = endadd[i-1]+cnt;
}
int total = 1;
flag[0] = 1;
while(m--){
int idx;cin>>idx;
if(idx>endadd[n-1]){
puts("Illegal Access");
}else{
int l = 0,r = n-1;
while(l<r){
int mid = l+r>>1;
if(endadd[mid]>=idx)r = mid;
else l=mid+1;
}
if(l==0) printf("%d\n",startadd[l]+idx*4);
else printf("%d\n",startadd[l]+4*(idx-endadd[l-1]-1));
}
}
}