• 【DFS序+树状数组】BNUOJ 52733 Random Numbers


    http://acm.bnu.edu.cn/v3/problem_show.php?pid=52733

    【题意】

    • 给定一棵树,这棵树每个点都有一个点权,标号从0开始,0是根结点
    • 修改操作:
      SEED 1 13
      把结点1的点权乘上13
    • 查询操作:
      RAND 1
      查询结点1为根的子树所有结点权的总乘积,以及这个总乘积有多少个因子
    • 题目保证结果的质因子最大为13

    【思路】

    • 质因子最大为13,那么我们可以枚举质因子2 3 5 7 11 13,共6个
    • 只要我们知道子树乘积这六个质因子的个数,我们就能算出子树的总乘积为2^p1*3^p2*5^p3*7^p4*11^p5*13^p6,而且这个数共有(p1+1)*(p2+1)*(p3+1)*(p4+1)*(p5+1)*(p6+1)个因子
    • 我们可以为每个质因子维护一个树状数组,统计因子个数和

    【AC】

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 
      5 const int maxn=1e5+2;;
      6 const int maxm=2*maxn;
      7 const ll mod=1e9+7;
      8 int n;
      9 struct edge
     10 {
     11     int to;
     12     int nxt;
     13 }e[maxm];
     14 int head[maxn];
     15 int tot;
     16 int l[maxn],r[maxn];
     17 int cid;
     18 ll tree[7][maxm];
     19 int p[7];
     20 ll fpow(ll x,ll n)
     21 {
     22     ll res=1;
     23     while(n)
     24     {
     25         if(n&1) res=(res*x)%mod;
     26         x=(x*x)%mod;
     27         n>>=1;
     28     }
     29     return res;
     30 }
     31 int lowbit(int x)
     32 {
     33     return x&(-x);
     34 }
     35 
     36 void add(int i,int k,int cnt)
     37 {
     38     while(k<=cid)
     39     {
     40         tree[i][k]+=cnt;
     41         k+=lowbit(k);
     42     }
     43 }
     44 ll query(int i,int k)
     45 {
     46     int res=1;
     47     while(k)
     48     {
     49         res+=tree[i][k];
     50         k-=lowbit(k);
     51     }
     52     return res;
     53 }
     54 void init()
     55 {
     56     memset(head,-1,sizeof(head));
     57     tot=0;
     58     cid=0;
     59     memset(tree,0,sizeof(tree));
     60 }
     61 void addedge(int u,int v)
     62 {
     63     e[tot].to=v;
     64     e[tot].nxt=head[u];
     65     head[u]=tot++;
     66 }
     67 void dfs(int u,int pa)
     68 {
     69     l[u]=++cid;
     70     for(int i=head[u];i!=-1;i=e[i].nxt)
     71     {
     72         int v=e[i].to;
     73         if(v==pa) continue;
     74         dfs(v,u);
     75     }
     76     r[u]=++cid;
     77 }
     78 
     79 void update(int i,ll x)
     80 {
     81     for(int j=1;j<=6;j++)
     82     {
     83         int cnt=0;
     84         while(x%p[j]==0)
     85         {
     86             cnt++;
     87             x/=p[j];
     88         }
     89         add(j,l[i],cnt);
     90     }
     91 }
     92 int main()
     93 {
     94     p[1]=2,p[2]=3,p[3]=5,p[4]=7,p[5]=11,p[6]=13;
     95     while(~scanf("%d",&n))
     96     {
     97         init();
     98         int u,v;
     99         for(int i=1;i<=n-1;i++)
    100         {
    101             scanf("%d%d",&u,&v);
    102             u++;v++;
    103             addedge(u,v);
    104             addedge(v,u);
    105         }    
    106         dfs(1,-1);
    107         for(int i=1;i<=n;i++)
    108         {
    109             ll x;
    110             scanf("%I64d",&x);
    111             update(i,x);
    112         }
    113         int q;
    114         scanf("%d",&q);
    115         char str[10];
    116         while(q--)
    117         {
    118             scanf("%s",str);
    119             if(str[0]=='R')
    120             {
    121                 int x;
    122                 scanf("%d",&x);
    123                 x++;
    124                 ll cnt=1;
    125                 ll ans=1;
    126                 for(int i=1;i<=6;i++)
    127                 {
    128                     int tmp=query(i,r[x])-query(i,l[x]-1);
    129                     cnt=cnt*(ll)(tmp+1)%mod;
    130                     ans=(ans*fpow(p[i],tmp))%mod;
    131                 }
    132                 printf("%I64d %d
    ",ans,cnt);
    133             }
    134             else
    135             {
    136                 int k;
    137                 ll x;
    138                 scanf("%d%I64d",&k,&x);
    139                 k++;
    140                 update(k,x); 
    141             } 
    142             
    143         }
    144     }
    145     return 0;
    146 }
    树状数组
  • 相关阅读:
    idea 使用 maven 下载 jar 包,出现证书校验问题问题
    接口抽象类区别,Java中IO,BIO、NIO、AIO区别以及Files的常用方法
    JIT编译器,Java平台的不同及Java一次编写,随处运行
    什么是Java虚拟机,JVM分配的不同类型内存区域是什么?
    AOP底层原理及AOP操作
    抽象类能使用 final 修饰吗?
    抽象类必须要有抽象方法吗?
    String 类的常用方法都有那些?
    普通类和抽象类有哪些区别?
    如何将字符串反转?
  • 原文地址:https://www.cnblogs.com/itcsl/p/7419974.html
Copyright © 2020-2023  润新知