1007 the 36th ACM/ICPC Asia Regional Shanghai site -- online contest 2011acm Shanghai site Competition
Can you answer these queries?
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4027
For example, if the number is 100000, 0 I j indicates that all numbers in the I j segment are taken as the root number (rounded down ), 1 I j indicates the sum of all values between I j... (The sum cannot exceed 64 bits )..
Analysis: the Key to this question is to understand that for any value within 64 bits, the root number cannot exceed 7 times. Therefore, we use the line segment tree for a maximum of 7 updates to the leaf node, therefore, if the number of root numbers in each query is large, the system returns directly. Otherwise, the system continues to update to the leaf node... Record several values of CNT indicates the number of updates in the current entire segment, add indicates the lazy to be updated downward, sum [] indicates that all values in this segment open the sum of the values of the 0 -- Max root number...
This is a bit similar to the hdu3954 method, http://blog.csdn.net/ggggiqnypgjg/article/details/6703082
Code:
#include <stdio.h>#include <string.h>#include <algorithm>#include <cmath>#include <iostream>using namespace std;const int N=100010;int n, m;struct node{int l, r, mid;int cnt, add;__int64 sum[8];} a[N*4];__int64 b[N], mx;int mxk;void build(int l, int r, int p){a[p].l = l;a[p].r = r;a[p].mid = (l+r)>>1;a[p].cnt = a[p].add = 0;int i;if(l==r){a[p].sum[0] = b[l];if(b[l]==0){for(i=1; i<=mxk; i++)a[p].sum[i] = 0;return ;}for(i=1; a[p].sum[i-1]>1; i++)a[p].sum[i] = sqrt((double)a[p].sum[i-1]);for( ;i<=mxk; i++)a[p].sum[i] = 1;return;}build(l, a[p].mid, p*2);build(a[p].mid+1, r, p*2+1);for(i=0; i<=mxk; i++)a[p].sum[i] = a[p*2].sum[i]+a[p*2+1].sum[i];}inline void down(int p){if(a[p].add!=0){a[p*2].cnt += a[p].add;a[p*2].add += a[p].add;a[p*2+1].cnt += a[p].add;a[p*2+1].add += a[p].add;a[p].add = 0;}}void update(int l, int r, int p){if(a[p].l==l && a[p].r==r){a[p].cnt += 1;a[p].add += 1;return;}down(p);if(r<=a[p].mid)update(l, r, p*2);else if(l>a[p].mid)update(l, r, p*2+1);else{update(l, a[p].mid, p*2);update(a[p].mid+1, r, p*2+1);}}__int64 query(int l, int r, int p){if(a[p].l==l && a[p].r==r){if(a[p].cnt>mxk)a[p].cnt = mxk;if(a[p].cnt==mxk || a[p].l==a[p].r)return a[p].sum[a[p].cnt];down(p);return query(l, a[p].mid, p*2)+query(a[p].mid+1, r, p*2+1);}down(p);if(r<=a[p].mid)return query(l, r, p*2);else if(l>a[p].mid)return query(l, r, p*2+1);elsereturn query(l, a[p].mid, p*2)+query(a[p].mid+1, r, p*2+1);}int main(){int i, cas1, op, x, y;cas1=1;while(scanf("%d", &n)!=EOF){mx = 0;for(i=1; i<=n; i++){scanf("%I64d", &b[i]);if(b[i]>mx)mx = b[i];}for(i=1; mx>1; i++, mx=sqrt((double)mx));mxk = i;build(1, n, 1);scanf("%d", &m);printf("Case #%d:\n", cas1++);while(m--){scanf("%d%d%d", &op, &x, &y);if(x>y)swap(x, y);if(op==0)update(x, y, 1);elseprintf("%I64d\n", query(x, y, 1));}printf("\n");}return 0;}
Competition code:
# Include <stdio. h> # include <string. h >#include <algorithm> # include <cmath> # include <iostream> using namespace STD; const int n = 200010; int n, m; struct node {int L, R, mid; int CNT, add; int FL, fr ;__ int64 sum [15];} A [n * 4] ;__ int64 B [N], MX; int mxk; void build (int l, int R, int p) {A [p]. L = L; A [p]. R = r; A [p]. mid = (L + r)> 1; A [p]. CNT = A [p]. add = 0; A [p]. FL = A [p]. fr = 0; int I; If (L = r) {A [p]. sum [0] = B [l]; If (B [l] = 0) {for (I = 1; I <= mxk; I ++) A [p]. sum [I] = 0; return;} for (I = 1; A [p]. sum [I-1]> 1; I ++) A [p]. sum [I] = (_ int64) SQRT (double) A [p]. sum [I-1]); For (; I <= mxk; I ++) A [p]. sum [I] = 1; return;} build (L, A [p]. mid, p * 2); Build (A [p]. mid + 1, R, p * 2 + 1); for (I = 0; I <= mxk; I ++) A [p]. sum [I] = A [p * 2]. sum [I] + A [p * 2 + 1]. sum [I];} inline void down (INT p) {if (a [p]. add! = 0) {A [p * 2]. CNT + = A [p]. add; A [p * 2]. add + = A [p]. add; A [p * 2 + 1]. CNT + = A [p]. add; A [p * 2 + 1]. add + = A [p]. add; A [p]. add = 0 ;}} void Update (int l, int R, int p) {if (a [p]. L = L & A [p]. R = r) {A [p]. CNT + = 1; A [p]. add + = 1; return;} Down (p); If (r <= A [p]. mid) {Update (L, R, p * 2); A [p]. FL = 1;} else if (L> A [p]. mid) {Update (L, R, p * 2 + 1); A [p]. fr = 1;} else {A [p]. FL = 1; A [p]. fr = 1; Update (L, A [p]. mid, p * 2); update (A [p]. mid + 1, R, p * 2 + 1) ;}__ Int64 query (int l, int R, int p) {if (a [p]. L = L & A [p]. R = r) {if (a [p]. CNT> mxk) A [p]. CNT = mxk; if (a [p]. CNT = mxk) return a [p]. sum [A [p]. CNT]; // If (A [p]. FL | A [p]. fr) = 0) // The CNT values are the same .. // Return a [p]. sum [A [p]. CNT]; if (a [p]. L = A [p]. r) return a [p]. sum [A [p]. CNT]; down (p); Return query (L, A [p]. mid, p * 2) + query (A [p]. mid + 1, R, p * 2 + 1);} Down (p); If (r <= A [p]. mid) return query (L, R, p * 2); else if (L> A [p]. mid) return query (L, R, p * 2 + 1); else {return query (L, A [p]. mid, p * 2) + query (A [p]. mid + 1, R, p * 2 + 1) ;}} int main () {// freopen ("D. in "," r ", stdin); // freopen (" D. out "," W ", stdout); int I, cas1, op, X, Y; cas1 = 1; W Hile (scanf ("% d", & N )! = EOF) {MX = 0; for (I = 1; I <= N; I ++) {scanf ("% i64d", & B [I]); if (B [I]> MX) MX = B [I] ;}for (I = 1; MX> 1; I ++, MX = (_ int64) SQRT (double) MX); mxk = I; mxk + = 3; build (1, n, 1); scanf ("% d", & M ); printf ("case # % d: \ n", cas1 ++); While (M --) {scanf ("% d", & OP, & X, & Y); If (x> Y) Swap (x, y); If (OP = 0) Update (X, Y, 1 ); elseprintf ("% i64d \ n", query (X, Y, 1);} printf ("\ n");} return 0 ;}