hdu 6161 Big binary tree

来源:互联网 发布:js跨域请求的几种方式 编辑:程序博客网 时间:2024/06/05 02:57
/*   最长距离    1 .当前x 为根节点的最长直径 ,或 一层一层往上走 包含x的一边 ,加另一部分最长半径。   设 ans[x] 为 以x 为根节点的 最长半径,   chance x, 只影响 x 和x 的祖先。   未影响的 ans 选择 最右的路径 或 从 n 往上爬  看是否爬到 x */ #include<iostream>#include<algorithm>#include<map>#include<cstdio>#include<cstring> typedef long long ll;#define ms(a) memset(a,0,sizeof(a))#define rep(i,a,b) for(int i=(a);i<=(b);++ i)#define Bug(x) cout<<x<<' '<<":)->ok"<<endl;using namespace std;map<int,ll> val,ans;int n,m;ll Ans=0;ll Value(int x){if(val.count(x)) return val[x];return x; }ll path(int x){if(ans.count(x)) return ans[x];if(x>n) return 0;ll s1=0,s2=0;int xx=x,nn=n;while(xx<=n){s1 +=xx;xx =2*xx+1;}while(nn>x){s2 +=nn;nn /=2;}return max(s1,nn==x?s2+x:0);}void query(int x){Ans=0;int root=x;ll al,ar,s1=0,f=2,s2;while(root){s1 +=Value(root);s2=s1;if(f!=0) s2 +=path(root*2);if(f!=1) s2 +=path(root*2+1);Ans = max(Ans,s2);if(f==2) s1 +=max(path(root*2),path(root*2+1));f =root&1; root >>=1;}}void change(int x,ll x1){val[x] =x1;ans[x]= x1 + max(path(x*2),path(x*2+1));x  /=2;while(x){ans[x] = Value(x) +max( path(x*2) , path(x*2+1) ); x /=2; }}int main(){   while(~scanf("%d%d",&n,&m))   {    ans.clear();    val.clear();     char que[10];     int x; ll x1;        while(m--)        {          scanf("%s",que);          if(que[0]=='q')   {  scanf("%d",&x);    query(x);   printf("%lld\n",Ans);      }          else  {   scanf("%d%lld",&x,&x1);   change(x,x1);  } }   }   return 0;}

原创粉丝点击