ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces 1654D - Potion Brewing Class

2022-04-04 13:02:53  阅读:143  来源: 互联网

标签:prime cnt Potion int ll Brewing maxn include 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  } 

 

标签:prime,cnt,Potion,int,ll,Brewing,maxn,include,Class
来源: https://www.cnblogs.com/2014nhc/p/16098870.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有