Uva1406-a Sequence of Numbers (tree-like array)
Topic links
main topic:
given n numbers, give two operations: C x: Add the N numbers to the X. Q x: Query How many numbers and 2^x are in this n number and are larger than 0. Finally, the result of each query is summed as an answer.
problem thinking:
Query and 2^x take and 1, then it means that the number of the requirements of the first X-position if 1.
But here's the whole plus x operation, you can use a variable to record all the x's and of the C operation. With this addend, the X-bit 1 may be obtained by a low-level carry, so there are 16 tree-like arrays, and the first tree-like array holds the values of each number starting from the low, continuous I-bit. For example 7: No. 0 Tree array plus 1, 1th tree array plus 3, 2nd tree array plus 7 ...
The next thing to discuss: first if Addend is 1XXX then 1) 1xxx + 0xxx = 1xxx This is eligible, and the 1xxx range "1000,1111". 2) 1xxx + 1xxx = 11xxx This is eligible, 11xxx range "11000,11111". Second, if it is 0xxx, it is divided into two cases, the same way to get the scope of "1000,1111". Finally, by subtracting the known addend, we can find out the range that meets the query requirements. In a tree-like array, count how many of the numbers in this range exist.
Note: To determine whether a bit 1 to use &, do not simply judge the size. There are also each addend in response to each query to remember to take the 2^ (x + 1). Because only the X-bits in the back are needed.
Code:
#include <cstdio>#include <cstring>#include <algorithm>using namespace STD;Const intM =7e4;Const intN = -;#Define lowbit (x) ((x) & ( ×))typedef Long LongllintNintT[n], c[n][m];voidAdd (intKintXintV) { while(x < M) {C[k][x] + = V; x + = Lowbit (x); }}ll sum (intKintx) {intRET =0; while(X >0) {ret + = c[k][x]; X-= Lowbit (x); }returnRET;}voidInit () {t[0] =1; for(inti =1; i < N; i++) T[i] = t[i-1] *2;}voidHandle (intNUM) { for(inti = N-1; I >=0; i--) {Add (i, num +1,1);if(Num >= t[i]) num-= T[i]; }}ll solve () {ll ans =0;intAddnum =0;Charstr[Ten];intX, L, R; while(scanf('%s ', str) && str[0] !=' E ') {scanf("%d", &x);if(str[0] ==' C ') Addnum = (addnum + x)% t[ -];Else{if(Addnum & T[x]) {L = t[x +1] + t[x]-addnum% t[x +1]; r = min (t[x +2] -1-Addnum% t[x +1], t[ -] -1); Ans + = SUM (x, R +1)-sum (x, L); } L = t[x]-addnum% t[x +1]; r = t[x +1] -1-Addnum% t[x +1]; Ans + = SUM (x, R +1)-sum (x, L);//printf ("%d%d%lld\n", Min, Max, ans);} }returnAns;}intMain () {init ();intCAS =0, Num; while(scanf("%d", &n) && n! =-1) {memsetC0,sizeof(C)); for(inti =0; I < n; i++) {scanf("%d", &num); handle (num); }printf("Case%d:%lld\n", ++cas, Solve ()); }return 0;}
Uva1406-a Sequence of Numbers (tree-like array)