int queryTree(int now, int pos, int sum) { if(pos <= TR && pos >= TL) { for(int k = 1; k < 11; ++ k) sum += TA[cout[k][pos % k]]; } if(TL == TR) return sum; if(pos <= TM) return queryTree(LSon, pos, sum); else return queryTree(RSon, pos, sum); }
int main() { int n, q; geti(n, q); for(int i = 1; i < n; i++) { int u, v; geti(u, v); u--; v--; adj[u].pb(v); adj[v].pb(u); } init(n); dfs(0, -1); HLD(0, -1); while(q--) { int type, x; geti(type, x); x--; if(type == 0) { updateTree(x); } else { printf("%d\n", queryTree(x)); } } }
int main() { int n = 0; for(int i = 1; i < 11; ++ i) for(int j = 0; j < i; ++ j) cout[i][j] = n ++; while(~scanf("%d", &n)) { BuildTree(1, 1, n); for(int i = 1; i <= n; ++ i) scanf("%d", &ele[i]); int q; scanf("%d", &q); while(q--) { int t; scanf("%d", &t); if(t == 1) { int a, b, k, c; scanf("%d %d %d %d", &a, &b, &k, &c); updateTree(1, a, b, k, c, a % k); } else { int a; scanf("%d", &a); int ans = queryTree(1, a, 0); printf("%d\n", ele[a] + ans); } } } return 0; }
int queryTree(int treeIndex, int lo, int hi, int i, int j) { if (hi < i || lo > j) return 0; if (i<=lo && j >= hi) { return tree[treeIndex]; } int mid = lo + (hi - lo)/2; if (i>mid) return queryTree(2*treeIndex+2,mid+1, hi, i,j); else if (j<=mid) return queryTree(2*treeIndex+1, lo, mid,i,j); int leftQuery = queryTree(2*treeIndex+1, lo, mid, i, mid); int rightQuery = queryTree(2*treeIndex+2, mid+1, hi, mid+1,j); return leftQuery + rightQuery; }
int queryTree(TreeNode* root, int row1, int col1, int row2, int col2){ if(root->tlRow == row1 && root->tlCol == col1 && root->brRow == row2 && root->brCol == col2) return root->sum; int midRow = root->tlRow + (root->brRow - root->tlRow) / 2; int midCol = root->tlCol + (root->brCol - root->tlCol) / 2; if(row2 <= midRow){ if(col2 <= midCol) return queryTree(root->nw, row1, col1, row2, col2); else if(col1 > midCol) return queryTree(root->ne, row1, col1, row2, col2); else return queryTree(root->nw, row1, col1, row2, midCol) + queryTree(root->ne, row1, midCol+1, row2, col2); } else if(row1 > midRow){ if(col2 <= midCol) return queryTree(root->sw, row1, col1, row2, col2); else if(col1 > midCol) return queryTree(root->se, row1, col1, row2, col2); else return queryTree(root->sw, row1, col1, row2, midCol) + queryTree(root->se, row1, midCol+1, row2, col2); } else{ if(col2 <= midCol) return queryTree(root->nw, row1, col1, midRow, col2) + queryTree(root->sw, midRow+1, col1, row2, col2); else if(col1 > midCol) return queryTree(root->ne, row1, col1, midRow, col2) + queryTree(root->se, midRow+1, col1, row2, col2); else return queryTree(root->nw, row1, col1, midRow, midCol) + queryTree(root->ne, row1, midCol+1, midRow, col2) + queryTree(root->sw, midRow+1, col1, row2, midCol) + queryTree(root->se, midRow+1, midCol+1, row2, col2); } }
int sumRegion(int row1, int col1, int row2, int col2){ return queryTree(root, row1, col1, row2, col2); }
void FastMKS<KernelType, TreeType>::Search( const typename TreeType::Mat& querySet, const size_t k, arma::Mat<size_t>& indices, arma::mat& kernels) { Timer::Start("computing_products"); // No remapping will be necessary because we are using the cover tree. indices.set_size(k, querySet.n_cols); kernels.set_size(k, querySet.n_cols); // Naive implementation. if (naive) { // Fill kernels. kernels.fill(-DBL_MAX); // Simple double loop. Stupid, slow, but a good benchmark. for (size_t q = 0; q < querySet.n_cols; ++q) { for (size_t r = 0; r < referenceSet.n_cols; ++r) { const double eval = metric.Kernel().Evaluate(querySet.col(q), referenceSet.col(r)); size_t insertPosition; for (insertPosition = 0; insertPosition < indices.n_rows; ++insertPosition) if (eval > kernels(insertPosition, q)) break; if (insertPosition < indices.n_rows) InsertNeighbor(indices, kernels, q, insertPosition, r, eval); } } Timer::Stop("computing_products"); return; } // Single-tree implementation. if (singleMode) { // Fill kernels. kernels.fill(-DBL_MAX); // Create rules object (this will store the results). This constructor // precalculates each self-kernel value. typedef FastMKSRules<KernelType, TreeType> RuleType; RuleType rules(referenceSet, querySet, indices, kernels, metric.Kernel()); typename TreeType::template SingleTreeTraverser<RuleType> traverser(rules); for (size_t i = 0; i < querySet.n_cols; ++i) traverser.Traverse(i, *referenceTree); Log::Info << rules.BaseCases() << " base cases." << std::endl; Log::Info << rules.Scores() << " scores." << std::endl; Timer::Stop("computing_products"); return; } // Dual-tree implementation. First, we need to build the query tree. We are // assuming it doesn't map anything... Timer::Stop("computing_products"); Timer::Start("tree_building"); TreeType queryTree(querySet); Timer::Stop("tree_building"); Search(&queryTree, k, indices, kernels); }