zoukankan      html  css  js  c++  java
  • [HAOI2015]树上操作

    【题目描述】

    有一棵点数为N的树,以点1为根,且树点有边权。然后有M个操作,分为三种:

    操作1:把某个节点x的点权增加a。

    操作2:把某个节点x为根的子树中所有点的点权都增加a。

    操作3:询问某个节点x到根的路径中所有点的点权和。

    【输入格式】

    第一行两个整数N,M,表示点数和操作数。

    接下来一行N个整数,表示树中节点的初始权值。

    接下来N-1行每行两个正整数fr,to,表示该树中存在一条边(fr,to)。

    再接下来M行,每行分别表示一次操作。其中第一个数表示该操作的种类(1~3),之后接这个操作的参数(x或者x a)。

    【输出格式】

    对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

    【样例输入】

    5 5

    1 2 3 4 5

    1 2

    1 4

    2 3

    2 5

    3 3

    1 2 1

    3 5

    2 1 2

    3 3

    【样例输出】

    6

    9

    13

    【提示】

    对于30%的数据,N,M<=1000

    对于50%的数据,N,M<=100000且数据随机。

    对于100%的数据,N,M<=100000,且所有输入数据的绝对值都不会超过10^6。

    很有思考性的题,所以贴出来。

    题解链接:http://www.cnblogs.com/Asm-Definer/p/4466729.html 

    1操作直接在BIT 操作,

    还要读入挂,OI真辛苦

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<math.h>
      4 #include<vector>
      5 #include<string.h>
      6 #include<string>
      7 #include<set>
      8 #include<iostream>
      9 using namespace std;
     10 typedef long long ll;
     11 #define N 153333
     12 
     13 vector<int>mp[N];
     14 int a[N],dep[N],st[N],ed[N],tot=1;
     15 ll f1[N],f2[N],c[N];
     16 int head[N];
     17 struct node
     18 {
     19     int v,next;
     20 }e[N<<1];
     21 int n,m;
     22 int lowbit(int x)
     23 {
     24     return x&-x;
     25 }
     26 
     27 void add1(int x,ll v)
     28 {
     29     for (int i=x;i<=n;i+=lowbit(i)) f1[i]+=v;
     30 }
     31 void add2(int x,ll v)
     32 {
     33     for (int i=x;i<=n;i+=lowbit(i)) f2[i]+=v;
     34 }
     35 ll query1(int x)
     36 {
     37     ll s=0;
     38     for (int i=x;i>0;i-=lowbit(i))
     39         s+=f1[i];
     40     return s;
     41 }
     42 ll query2(int x)
     43 {
     44     ll s=0;
     45     for (int i=x;i>0;i-=lowbit(i))
     46         s+=f2[i];
     47     return s;
     48 }
     49 
     50 void dfs(int u,int pre,int t,ll sum)
     51 {
     52     st[u]=tot++;
     53     dep[u]=t;
     54     sum+=a[u];
     55     c[u]=sum;
     56     for (int i=head[u];i!=-1;i=e[i].next)
     57     {
     58         int v=e[i].v;
     59         if (v==pre) continue;
     60         dfs(v,u,t+1,sum);
     61     }
     62     ed[u]=tot-1;
     63 }
     64 void judge()
     65 {
     66     freopen("haoi2015_t2.in","r",stdin);
     67     freopen("haoi2015_t2.out","w",stdout);
     68 
     69 }
     70 int tt;
     71 void add(int u,int v)
     72 {
     73     e[tt].v=v;
     74     e[tt].next=head[u];
     75     head[u]=tt++;
     76 }
     77 
     78 void Getz(int &x){
     79     int ch;
     80     while(ch=getchar(),ch<48||ch>57);x=ch-48;
     81     while(ch=getchar(),ch>47&&ch<58) x=x*10+ch-48;
     82 }
     83 int main()
     84 {
     85     judge();
     86     tt=0;
     87     memset(head,-1,sizeof(head));
     88     //scanf("%d%d",&n,&m);
     89     Getz(n); 
     90     Getz(m);
     91     for (int i=1;i<=n;i++) Getz(a[i]);
     92     for (int i=1;i<n;i++)
     93     {
     94         int x,y;
     95        // scanf("%d%d",&x,&y);
     96         Getz(x); Getz(y);
     97         //mp[x].push_back(y);
     98         add(x,y);
     99         add(y,x);
    100         //mp[y].push_back(x);
    101     }
    102     dfs(1,-1,1,0);
    103 //    for (int i=1;i<=n;i++)
    104   //      cout<<st[i]<<" "<<ed[i]<<endl;
    105 
    106     while (m--)
    107     {
    108         int op,u,v;
    109         scanf("%d",&op);
    110         if (op==1)
    111         {
    112             //scanf("%d%d",&u,&v);
    113             Getz(u); Getz(v);
    114             add2(st[u],v);add2(ed[u]+1,-v);
    115         }else if (op==2)
    116         {
    117             // scanf("%d%d",&u,&v);
    118              Getz(u); Getz(v);
    119              ll tmp=1-dep[u];
    120              tmp*=v;
    121              add1(st[u],v),add1(ed[u]+1,-v);
    122              add2(st[u],tmp),add2(ed[u]+1,-tmp);
    123         }
    124         else
    125         {
    126              //scanf("%d",&u);
    127              Getz(u);
    128              printf("%lld ",c[u]+query1(st[u])*dep[u]+query2(st[u]));
    129         }
    130     }
    131 
    132     return 0;

    133 } 

  • 相关阅读:
    6、CC2541修改按键调节广播发送功率例程为持续发送4DB的蓝牙基站
    [nRF51822] 16、nRF51822的随机数生成器,及随机数生成器的一些知识(可以帮您补补随机数发生器的知识)
    [PCB设计] 4、BAT脚本处理AD生成的GERBER文件为生产文件
    [异常解决] 奇巧淫技——VirtualBox中的linux无显示启动,并在win7上远程控制
    [PCB设计] 3、用CAM350修改GERBER文件(删除某些部分)
    [异常解决] Make nRF51 DFU Project Appear "fatal error: uECC.h: No such file or directory"
    [异常解决] How to build a gcc toolchain for nRF51 on linux (very detailed!!!)
    [异常解决] windows用SSH和linux同步文件&linux开启SSH&ssh client 报 algorithm negotiation failed的解决方法之一
    [模拟电路] 2、Passive Band Pass Filter
    Docker常用命令
  • 原文地址:https://www.cnblogs.com/forgot93/p/4847732.html
Copyright © 2011-2022 走看看