zoukankan      html  css  js  c++  java
  • Bzoj 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 17222  Solved: 7033
    [Submit][Status][Discuss]

    Description

      一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
    一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
    II. 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
    这是立志换码风(多打几个回车)后的第一个题
    写完之后拼命地wa,自己瞎改了两下,随手删了几个小地方,就A了
    我也不知道为什么
      1 /*
      2     qsum和qmax两个函数中的if(x!=y)要去掉
      3     主函数中的特判if(x==y)printf("%d
    ",value[x]);和if(x==y)printf("%d
    ",value[x]);要去掉
      4 */
      5 #include<iostream>
      6 #include<cstdio>
      7 using namespace std;
      8 
      9 #define maxn 300100
     10 #define inf 0x7fffffff
     11 int m,n,head[maxn],num,dep[maxn],son[maxn],sz[maxn],pos[maxn],top[maxn],idx,father[maxn],value[maxn];
     12 
     13 struct edge{
     14     int to,pre;
     15 }e[maxn*3];
     16 
     17 void addedge(int from,int to){
     18     e[++num].to=to;
     19     e[num].pre=head[from];
     20     head[from]=num;
     21     
     22     e[++num].to=from;
     23     e[num].pre=head[to];
     24     head[to]=num;
     25 }
     26 
     27 void dfs_find(int fa,int u){
     28     dep[u]=dep[fa]+1;
     29     sz[u]=1;
     30     son[u]=0;
     31     father[u]=fa;
     32     for(int i=head[u];i;i=e[i].pre){
     33         int v=e[i].to;
     34         if(v==fa)continue;
     35         dfs_find(u,v);
     36         sz[u]+=sz[v];
     37         if(sz[v]>sz[son[u]]||son[u]==0)son[u]=v;
     38     }
     39 }
     40 
     41 void dfs_time(int fa,int u){
     42     pos[u]=++idx;top[u]=fa;
     43     if(son[u]!=0)dfs_time(top[u],son[u]);
     44     for(int i=head[u];i;i=e[i].pre){
     45         int v=e[i].to;
     46         if(v==father[u]||v==son[u])continue;
     47         dfs_time(v,v);
     48     }
     49 }
     50 
     51 struct tree{
     52     int l,r,mx,sum;
     53 }tr[maxn<<2];
     54 void build(int l,int r,int k){
     55     tr[k].l=l;tr[k].r=r;tr[k].mx=-inf;tr[k].sum=0;
     56     if(l==r)return;
     57     int mid=(l+r)>>1;
     58     build(l,mid,k<<1);
     59     build(mid+1,r,k<<1|1);
     60 }
     61 void update(int p,int v,int k){
     62     if(tr[k].l==tr[k].r){tr[k].mx=tr[k].sum=v;return;}
     63     int mid=(tr[k].l+tr[k].r)>>1;
     64     if(p<=mid)update(p,v,k<<1);
     65     else if(p>mid)update(p,v,k<<1|1);
     66     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     67     tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
     68 }
     69 int findsum(int l,int r,int k){
     70     if(tr[k].l==l&&tr[k].r==r)return tr[k].sum;
     71     int mid=(tr[k].l+tr[k].r)>>1;
     72     if(r<=mid)return findsum(l,r,k<<1);
     73     else if(l>mid)return findsum(l,r,k<<1|1);
     74     else return findsum(l,mid,k<<1)+findsum(mid+1,r,k<<1|1);
     75 }
     76 int qsum(int x,int y){
     77     int ans=0;
     78     while(top[x]!=top[y]){
     79         if(dep[top[x]]<dep[top[y]])swap(x,y);
     80         ans+=findsum(pos[top[x]],pos[x],1);
     81         x=father[top[x]];
     82     }
     83     if(dep[x]>dep[y])swap(x,y);
     84     if(x!=y)ans+=findsum(pos[x],pos[y],1);
     85     return ans;
     86 }
     87 int findmax(int l,int r,int k){
     88     if(tr[k].l==l&&tr[k].r==r)return tr[k].mx;
     89     int mid=(tr[k].l+tr[k].r)>>1;
     90     if(r<=mid)return findmax(l,r,k<<1);
     91     else if(l>mid)return findmax(l,r,k<<1|1);
     92     else return max(findmax(l,mid,k<<1),findmax(mid+1,r,k<<1|1));
     93 }
     94 int qmax(int x,int y){
     95     int ans=-inf;
     96     while(top[x]!=top[y]){
     97         if(dep[top[x]]<dep[top[y]])swap(x,y);
     98         ans=max(ans,findmax(pos[top[x]],pos[x],1));
     99         x=father[top[x]];
    100     }
    101     if(dep[x]>dep[y])swap(x,y);
    102     if(x!=y)ans=max(ans,findmax(pos[x],pos[y],1));
    103     return ans;
    104 }
    105 char c[10];
    106 int main(){
    107     scanf("%d",&n);
    108     int x,y;
    109     for(int i=1;i<n;i++){
    110         scanf("%d%d",&x,&y);
    111         addedge(x,y);
    112     }
    113     idx=0;
    114     dfs_find(1,1);
    115     dfs_time(1,1);
    116     build(1,n,1);
    117     for(int i=1;i<=n;i++){
    118         scanf("%d",&value[i]);
    119         update(pos[i],value[i],1);
    120     }
    121     
    122     scanf("%d",&m);
    123     for(int i=1;i<=m;i++){
    124         scanf("%s",c);scanf("%d%d",&x,&y);
    125         if(c[1]=='S'){
    126             if(x==y)printf("%d
    ",value[x]);
    127             else printf("%d
    ",qsum(x,y));
    128         }
    129         if(c[1]=='M'){
    130             if(x==y)printf("%d
    ",value[x]);
    131             else printf("%d
    ",qmax(x,y));
    132         }
    133         
    134         if(c[1]=='H')update(pos[x],y,1);
    135     }
    136 }
    10分 两处小八哥
      1 #include<iostream>
      2 #include<cstdio>
      3 using namespace std;
      4 
      5 #define maxn 300100
      6 #define inf 0x7fffffff
      7 int m,n,head[maxn],num,dep[maxn],son[maxn],sz[maxn],pos[maxn],top[maxn],idx,father[maxn],value[maxn];
      8 
      9 struct edge{
     10     int to,pre;
     11 }e[maxn*3];
     12 
     13 void addedge(int from,int to){
     14     e[++num].to=to;
     15     e[num].pre=head[from];
     16     head[from]=num;
     17     
     18     e[++num].to=from;
     19     e[num].pre=head[to];
     20     head[to]=num;
     21 }
     22 
     23 void dfs_find(int fa,int u){
     24     dep[u]=dep[fa]+1;
     25     sz[u]=1;
     26     son[u]=0;
     27     father[u]=fa;
     28     for(int i=head[u];i;i=e[i].pre){
     29         int v=e[i].to;
     30         if(v==fa)continue;
     31         dfs_find(u,v);
     32         sz[u]+=sz[v];
     33         if(sz[v]>sz[son[u]]||son[u]==0)son[u]=v;
     34     }
     35 }
     36 
     37 void dfs_time(int fa,int u){
     38     pos[u]=++idx;top[u]=fa;
     39     if(son[u]!=0)dfs_time(top[u],son[u]);
     40     for(int i=head[u];i;i=e[i].pre){
     41         int v=e[i].to;
     42         if(v==father[u]||v==son[u])continue;
     43         dfs_time(v,v);
     44     }
     45 }
     46 
     47 struct tree{
     48     int l,r,mx,sum;
     49 }tr[maxn<<2];
     50 void build(int l,int r,int k){
     51     tr[k].l=l;tr[k].r=r;tr[k].mx=-inf;tr[k].sum=0;
     52     if(l==r)return;
     53     int mid=(l+r)>>1;
     54     build(l,mid,k<<1);
     55     build(mid+1,r,k<<1|1);
     56 }
     57 void update(int p,int v,int k){
     58     if(tr[k].l==tr[k].r){tr[k].mx=tr[k].sum=v;return;}
     59     int mid=(tr[k].l+tr[k].r)>>1;
     60     if(p<=mid)update(p,v,k<<1);
     61     else if(p>mid)update(p,v,k<<1|1);
     62     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     63     tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
     64 }
     65 int findsum(int l,int r,int k){
     66     if(tr[k].l==l&&tr[k].r==r)return tr[k].sum;
     67     int mid=(tr[k].l+tr[k].r)>>1;
     68     if(r<=mid)return findsum(l,r,k<<1);
     69     else if(l>mid)return findsum(l,r,k<<1|1);
     70     else return findsum(l,mid,k<<1)+findsum(mid+1,r,k<<1|1);
     71 }
     72 int qsum(int x,int y){
     73     int ans=0;
     74     while(top[x]!=top[y]){
     75         if(dep[top[x]]<dep[top[y]])swap(x,y);
     76         ans+=findsum(pos[top[x]],pos[x],1);
     77         x=father[top[x]];
     78     }
     79     if(dep[x]>dep[y])swap(x,y);
     80     /*if(x!=y)*/ans+=findsum(pos[x],pos[y],1);
     81     return ans;
     82 }
     83 int findmax(int l,int r,int k){
     84     if(tr[k].l==l&&tr[k].r==r)return tr[k].mx;
     85     int mid=(tr[k].l+tr[k].r)>>1;
     86     if(r<=mid)return findmax(l,r,k<<1);
     87     else if(l>mid)return findmax(l,r,k<<1|1);
     88     else return max(findmax(l,mid,k<<1),findmax(mid+1,r,k<<1|1));
     89 }
     90 int qmax(int x,int y){
     91     int ans=-inf;
     92     while(top[x]!=top[y]){
     93         if(dep[top[x]]<dep[top[y]])swap(x,y);
     94         ans=max(ans,findmax(pos[top[x]],pos[x],1));
     95         x=father[top[x]];
     96     }
     97     if(dep[x]>dep[y])swap(x,y);
     98     /*if(x!=y)*/ans=max(ans,findmax(pos[x],pos[y],1));
     99     return ans;
    100 }
    101 char c[10];
    102 int main(){
    103     scanf("%d",&n);
    104     int x,y;
    105     for(int i=1;i<n;i++){
    106         scanf("%d%d",&x,&y);
    107         addedge(x,y);
    108     }
    109     idx=0;
    110     dfs_find(1,1);
    111     dfs_time(1,1);
    112     build(1,n,1);
    113     for(int i=1;i<=n;i++){
    114         scanf("%d",&value[i]);
    115         update(pos[i],value[i],1);
    116     }
    117     
    118     scanf("%d",&m);
    119     for(int i=1;i<=m;i++){
    120         scanf("%s",c);scanf("%d%d",&x,&y);
    121         if(c[1]=='S') printf("%d
    ",qsum(x,y));
    122         if(c[1]=='M') printf("%d
    ",qmax(x,y));
    123         
    124         if(c[1]=='H')update(pos[x],y,1);
    125     }
    126 }
    100 分
  • 相关阅读:
    Day 9 作业题(完成)
    Day 9 函数的初识1
    Day 8 集合与文件的操作
    Day 7 深copy和浅Copy
    Day6 ,周期末考试试题
    Day 6 编码的进阶
    Day5 作业(完成)
    Day 5 字典的操作
    Day4 作业
    Day 4 list 列表的使用方法
  • 原文地址:https://www.cnblogs.com/thmyl/p/7200066.html
Copyright © 2011-2022 走看看