每次改变log个点,map啥的存一存就好。
#include<bits/stdc++.h> #define LL long long using namespace std; int n, m, max_dep; map<int, LL> Map, pval; char op[10]; void init() { Map.clear(); pval.clear(); max_dep = 0; } LL get(int x) { if(x > n) return 0; int cur = x; auto it = Map.find(x); if(it != Map.end()) return it->second; LL ret = 0; int depth = 0; while((1 << depth) <= x) depth++; while(x <= n) { ret += x; if((++depth) > max_dep) break; LL lval = (x << 1) << (max_dep - depth); LL rval = (x << 1 | 1) << (max_dep - depth); if(lval <= n && rval <= n || lval > n && lval > n) x = (x << 1 | 1); else x = (x << 1); } return Map[cur] = ret; } LL getP(int x) { auto it = pval.find(x); if(it != pval.end()) return it->second; return x; } void modify(int x, LL val) { LL lval, rval; pval[x] = val; while(x) { lval = get(x << 1); rval = get(x << 1 | 1); Map[x] = max(lval, rval) + getP(x); x /= 2; } } LL query(int x) { LL ret = get(x << 1) + get(x << 1 | 1) + getP(x); LL now = get(x); int pa = x >> 1; while(pa) { now += getP(pa); if(x & 1) ret = max(ret, get(pa << 1) + now); else ret = max(ret, get(pa << 1 | 1) + now); x >>= 1; pa >>= 1; } return ret; } int main() { while(scanf("%d%d", &n, &m) != EOF) { init(); while((1 << max_dep) <= n) max_dep++; while(m--) { scanf("%s", op); if(*op == ‘c‘) { int u, x; scanf("%d%d", &u, &x); modify(u, x); } else { int u; scanf("%d", &u); printf("%lld\n", query(u)); } } } return 0; } /* */
原文:https://www.cnblogs.com/CJLHY/p/11666605.html