• Codeforces 1654D Potion Brewing Class


    问题:最开始的思路是找到最小的部分,然后根据倍数计算,但是实在不知道怎么比较两个数的大小

    答案:其实答案应该是对于每一个点i,i的成分大小应该是对于每一个其他点,比例中分母质数分解使每个质数最大时的乘积(因为需要能整除),但这样得到的结果是O(n^2),所以需要由一个点能直接推到多个点,其实已知一个成分的多少后保留倍数即可推到另外的点。

    所以时间复杂度主要在于质因数的预处理。

    记得注意fp函数不可以在f一边改的时候一边更新,因为分母分子不一定互质,所以要都改完以后再更新

    代码:

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstdio>
      4 #include<queue>
      5 #include<cmath>
      6 typedef long long ll;
      7 #define maxn 200000
      8 using namespace std;
      9 struct ding
     10 {
     11     int to,w1,w2,nex;
     12 }e[4*maxn];
     13 int cnt=0,n,h[2*maxn],prime[2*maxn],id[2*maxn],mini[2*maxn];
     14 vector<int>v[maxn*2];
     15 bool check[2*maxn];
     16 ll ans=0,val;
     17 ll mo=998244353; 
     18 int len,f[2*maxn],fp[2*maxn];
     19 void pre()
     20 {
     21     for (int i=1;i<=maxn;i++) check[i]=false;
     22     for (int i=2;i<=maxn;i++)
     23     {
     24         if (!check[i]) id[i]=len,prime[len++]=i,mini[i]=i;
     25         for (int j=0;j<len;j++)
     26         {
     27             if (i*prime[j]>maxn) break;
     28             check[i*prime[j]]=true;
     29             mini[i*prime[j]]=prime[j];
     30             if (i%prime[j]==0) break;
     31         }
     32     }
     33     for (int i=2;i<=maxn;i++)
     34     {
     35         int now=i;
     36         while (now!=1)
     37         {
     38             v[i].push_back(id[mini[now]]);
     39             now=now/mini[now];
     40         }
     41     }
     42 }
     43 ll poww(ll x,ll t)
     44 {
     45     if (t<0) return poww(poww(x,mo-2),-t);
     46     if (t==0) return 1ll;
     47     ll sum=1ll;
     48     x=x%mo;
     49     for (t;t>0;t=t>>(1ll)) 
     50     {
     51         if (t&(1ll)) sum=(sum*x)%mo;
     52         x=(x*x)%mo;
     53     }
     54     return sum%mo;
     55 }
     56 void add(int x,int y,ll v1,ll v2)
     57 {
     58     e[++cnt].to=y;
     59     e[cnt].w1=v1;
     60     e[cnt].w2=v2;
     61     e[cnt].nex=h[x];
     62     h[x]=cnt;
     63 }
     64 void dfs(int x,int fa)
     65 {
     66     for (int i=h[x];i;i=e[i].nex)
     67     {
     68         if (e[i].to==fa) continue;
     69         int t=e[i].to;
     70         int tot1=v[e[i].w1].size();
     71         int tot2=v[e[i].w2].size();
     72         for (int j=0;j<tot1;j++) --f[v[e[i].w1][j]];
     73         for (int j=0;j<tot2;j++) ++f[v[e[i].w2][j]];
     74         dfs(t,x);
     75         for (int j=0;j<tot1;j++) fp[v[e[i].w1][j]]=min(fp[v[e[i].w1][j]],f[v[e[i].w1][j]]);
     76         for (int j=0;j<tot2;j++) fp[v[e[i].w2][j]]=min(fp[v[e[i].w2][j]],f[v[e[i].w2][j]]);
     77         for (int j=0;j<tot1;j++) f[v[e[i].w1][j]]++;
     78         for (int j=0;j<tot2;j++) f[v[e[i].w2][j]]--;
     79     }
     80 }
     81 void dfs2(int x,ll now,int fa)
     82 {
     83     for (int i=h[x];i;i=e[i].nex)
     84     {
     85         int t=e[i].to;
     86         if (t==fa) continue;
     87         int tot1=v[e[i].w1].size();
     88         int tot2=v[e[i].w2].size();
     89         for (int j=0;j<tot1;j++) now=(now*poww(prime[v[e[i].w1][j]],mo-2))%mo;
     90         for (int j=0;j<tot2;j++) now=(now*prime[v[e[i].w2][j]])%mo;
     91         ans=(ans+now)%mo; 
     92         dfs2(t,now,x);
     93         for (int j=0;j<tot1;j++) now=(now*prime[v[e[i].w1][j]])%mo;
     94         for (int j=0;j<tot2;j++) now=(now*poww(prime[v[e[i].w2][j]],mo-2))%mo;
     95     }
     96 }
     97 int main()
     98 {
     99     int cas,n;
    100     cin>>cas;
    101     pre();
    102     while (cas--)
    103     {
    104         cin>>n;
    105         for (int i=1;i<=n;i++) h[i]=0; 
    106         cnt=0;
    107         int maxl=0;
    108         for (int i=0;i<len;i++)
    109         if (prime[i]<=n) maxl++;
    110         else break; 
    111         maxl=len;
    112         //cout<<maxl<<"!"<<endl;
    113         for (int i=0;i<maxl;i++) f[i]=fp[i]=0;
    114         int x,y;
    115         ll v1,v2;
    116         for (int i=1;i<n;i++)
    117         {
    118             scanf("%d%d%lld%lld",&x,&y,&v1,&v2);
    119             add(x,y,v1,v2);
    120             add(y,x,v2,v1);
    121         }
    122         dfs(1,0);
    123         val=1ll; 
    124         for (int i=0;i<maxl;i++) 
    125         {
    126             //if (-fp[i]!=0) cout<<prime[i]<<" "<<fp[i]<<endl;
    127             val=(val*poww(prime[i],-fp[i]))%mo; 
    128         }
    129         ans=1ll;
    130         dfs2(1,1,0);
    131         ans=(ans*val)%mo;
    132         cout<<ans<<endl;
    133     }
    134     return 0;
    135  } 
  • 相关阅读:
    linux 文件系统管理三部曲之二:创建文件系统
    linux 文件系统管理三部曲之一:磁盘分区
    Django 链接MySQL及数据操作
    redis事务
    redis配置文件详解
    redis中hash数据类型
    redis的基础知识
    redis两种持久化方式RDB和AOF
    git命令
    .gitignore中添加的某个忽略文件并不生效
  • 原文地址:https://www.cnblogs.com/2014nhc/p/16098870.html
Copyright © 2020-2023  润新知