• bzoj1036


    树链剖分模版吧。。。

      1 #include<bits/stdc++.h>
      2 #define l(a) ((a)<<1)
      3 #define r(a) (((a)<<1)+1)
      4 #define Rep(i,a) for(int i=0;i<e[a].size();i++)
      5 #define rep(i,l,r) for(int i=l;i<r;i++)
      6 #define lowbit(a) ((a)&(-(a)))
      7 #define clr(a,x) memset(a,x,sizeof(a))
      8 typedef long long ll;
      9 typedef unsigned long long ul;
     10 using namespace std;
     11 int read(){
     12     int ans=0,f=1;
     13     char c=getchar();
     14     while(!isdigit(c)){
     15         if(c=='-') f=-1;
     16         c=getchar();
     17     }
     18     while(isdigit(c)){
     19         ans=ans*10+c-'0';
     20         c=getchar();
     21     }
     22     return ans*f;
     23 }
     24 const int maxn=30050,inf=0x7fffffff;
     25 int n,m,u,v,idcnt=0,id[maxn],idr[maxn],dep[maxn],w[maxn],f[maxn],top[maxn],size[maxn],son[maxn];
     26 vector<int>e[maxn];
     27 void dfs(int x){
     28     size[x]=1;
     29     Rep(i,x){
     30         int to=e[x][i];
     31         if(to==f[x]) continue;
     32         dep[to]=dep[x]+1;
     33         f[to]=x;
     34         dfs(to);
     35         if(!son[x]||size[to]>size[son[x]]) son[x]=to;
     36         size[x]+=size[to];
     37     }
     38 }
     39 int Top; 
     40 void Dfs(int x){
     41     id[x]=++idcnt;
     42     idr[id[x]]=x;
     43     top[x]=Top;
     44     if(son[x]) Dfs(son[x]);
     45     Rep(i,x) if(!id[e[x][i]]) Dfs(Top=e[x][i]);
     46 }
     47 struct node{
     48     int l,r,sum,mx;
     49 };
     50 node x[maxn<<2];
     51 void maintain(int k){
     52     x[k].sum=x[l(k)].sum+x[r(k)].sum;
     53     x[k].mx=max(x[l(k)].mx,x[r(k)].mx);
     54 }
     55 void update(int k){
     56     if(x[k].l==x[k].r){
     57         x[k].sum=x[k].mx=v;
     58         return;
     59     }
     60     int mid=(x[k].l+x[k].r)>>1;
     61     update(u<=mid?l(k):r(k));
     62     maintain(k); 
     63 }
     64 int findmx(int k,int l,int r){
     65     if(x[k].l==l&&x[k].r==r) return x[k].mx;
     66     int mid=(x[k].l+x[k].r)>>1;
     67     if(l>mid) return findmx(r(k),l,r);
     68     if(r<=mid) return findmx(l(k),l,r);
     69     return max(findmx(l(k),l,mid),findmx(r(k),mid+1,r));
     70 }
     71 int findsum(int k,int l,int r){
     72     if(x[k].l==l&&x[k].r==r) return x[k].sum;
     73     int mid=(x[k].l+x[k].r)>>1;
     74     if(l>mid) return findsum(r(k),l,r);
     75     if(r<=mid) return findsum(l(k),l,r);
     76     return findsum(l(k),l,mid)+findsum(r(k),mid+1,r);
     77 }
     78 int askmx(){
     79     int ans=-inf;
     80     while(top[u]!=top[v]){
     81         if(dep[top[u]]<dep[top[v]]) swap(u,v);
     82         ans=max(ans,findmx(1,id[top[u]],id[u]));
     83         u=f[top[u]];
     84     }
     85     if(dep[u]>dep[v]) swap(u,v);
     86     ans=max(ans,findmx(1,id[u],id[v]));
     87     return ans;
     88 }
     89 int asksum(){
     90     int ans=0;
     91     while(top[u]!=top[v]){
     92         if(dep[top[u]]<dep[top[v]]) swap(u,v);
     93         ans+=findsum(1,id[top[u]],id[u]);
     94         u=f[top[u]];
     95     }
     96     if(dep[u]>dep[v]) swap(u,v);
     97     ans+=findsum(1,id[u],id[v]);
     98     return ans;
     99 }
    100 void build(int k,int l,int r){
    101     x[k].l=l,x[k].r=r;
    102     if(l==r){
    103         x[k].mx=x[k].sum=w[idr[l]];
    104         return;
    105     }
    106     int mid=(l+r)>>1;
    107     build(l(k),l,mid);
    108     build(r(k),mid+1,r);
    109     maintain(k);
    110 }
    111 void init(){
    112     dep[1]=0;
    113     dfs(1);Dfs(Top=1);
    114     build(1,1,n);
    115 }
    116 int main()
    117 {    
    118     n=read();
    119     rep(i,0,n-1){
    120         int from=read(),to=read();
    121         e[from].push_back(to);
    122         e[to].push_back(from);
    123     }
    124     rep(i,1,n+1) w[i]=read();
    125     init();    
    126     m=read();
    127     while(m--){
    128         char c[10];
    129         scanf(" %s",c);
    130         u=read(),v=read();
    131         if(c[0]=='C'){
    132             u=id[u];
    133             update(1);
    134         }else if(c[1]=='M'){
    135             printf("%d
    ",askmx());
    136         }else{
    137             printf("%d
    ",asksum());
    138         }
    139     }
    140     return 0;
    141 }
    View Code

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 8247  Solved: 3355
    [Submit][Status][Discuss]

    Description

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

    Input

    输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

    Output

    对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

    Sample Input

    4
    1 2
    2 3
    4 1
    4 2 1 3
    12
    QMAX 3 4
    QMAX 3 3
    QMAX 3 2
    QMAX 2 3
    QSUM 3 4
    QSUM 2 1
    CHANGE 1 5
    QMAX 3 4
    CHANGE 3 6
    QMAX 3 4
    QMAX 2 4
    QSUM 3 4

    Sample Output

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16

    HINT

     

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    小白学开发(iOS)OC_ 使用继承来扩充类(2015-08-07)
    UI组件之TextView及其子类(三)ToggleButton和Switch
    C++智能指针--shared_ptr
    HDU 1013 Digital Roots 题解
    对touch事件传递的简单理解
    【LeetCode-面试算法经典-Java实现】【096-Unique Binary Search Trees(唯一二叉搜索树)】
    Cocos2d-x 坐标系
    hdu1518 Square
    servlet3.0新特性
    OGNL表达式
  • 原文地址:https://www.cnblogs.com/chensiang/p/4696861.html
Copyright © 2020-2023  润新知