标签:div open turn 转移 int 颜色 条件 view ack
E题:
题意:
给定长度为N的序列A,求一个序列B,使得AiBi=AjBj(1<i<j<=n),且所有在序列B里的数最小,求这个最小值。
思路:
其实就是让所有AiBi都相等,所以就让AiBi=lcm(A1,A2,...,AN)就行了。
所以可以所有Ai出现过的质因数,把它们乘起来就是lcm(A1,A2,...,AN),最后让每一个A中的数除一下这个最小公倍数再求和就行了。
代码:
1 #pragma GCC optimize(3) 2 #include<bits/stdc++.h> 3 #define int long long 4 using namespace std; 5 int n,a[10005],f[1000005],mod=1e9+7; 6 int inv[1000005]; 7 signed main(){ 8 cin>>n; 9 for(int i=1;i<=n;i++){ 10 cin>>a[i]; 11 int t=a[i]; 12 for(int j=2;j*j<=a[i];j++){ 13 if(t%j==0){ 14 int sum=0; 15 while(t%j==0){ 16 t/=j;sum++; 17 } 18 f[j]=max(f[j],sum); 19 } 20 } 21 if(t!=1){ 22 if(!f[t])f[t]=1; 23 } 24 } 25 int p=1; 26 for(int i=2;i<1000000;i++){ 27 for(int j=0;j<f[i];j++)p=p*i%mod; 28 } 29 inv[1]=1; 30 for(int i=2;i<=1000000;i++)inv[i]=mod-inv[mod%i]*(mod/i)%mod; 31 int ans=0; 32 for(int i=1;i<=n;i++){ 33 ans=ans+p*inv[a[i]]; 34 ans=ans%mod; 35 } 36 cout<<ans; 37 return 0; 38 }
F题:
题意:
给一棵树,每条边都可以被染成黑或白两种颜色,给一些限制条件,两点之间的最短路径中最少有一条边为黑。
求符合要求的染色方案有多少种。
思路:
因为限制很少,可以用状压DP,dp[i][j]表示在只让前i条边变为黑的情况下,限制的状态为j的方案数。
转移要先预处理每条边染黑能让那几个限制成立,然后考虑在一种状态下把一条边染成黑色得到的状态都加上原来那种情况的方案数。
代码:
1 #pragma GCC optimize(3) 2 #include<bits/stdc++.h> 3 #define int long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 int dp[55][(1<<20)],n,m; 17 V<int> v[55],g[55]; 18 int fa[55],de[55]; 19 int er[25]; 20 void dfs(int p){ 21 for(int i=0;i<v[p].size();i++){ 22 if(fa[p]!=v[p][i]){ 23 fa[v[p][i]]=p; 24 de[v[p][i]]=de[p]+1; 25 dfs(v[p][i]); 26 } 27 } 28 } 29 void get(int l,int r,int s){ 30 if(de[l]>de[r])swap(l,r); 31 while(de[r]>de[l]){ 32 g[r].PB(s);r=fa[r]; 33 } 34 while(l!=r){ 35 g[l].PB(s);l=fa[l]; 36 g[r].PB(s);r=fa[r]; 37 } 38 } 39 signed main(){ 40 ios::sync_with_stdio(0); 41 cin.tie(0); 42 int x,y; 43 cin>>n; 44 FOR(i,2,n){ 45 cin>>x>>y;v[x].PB(y);v[y].PB(x); 46 } 47 fa[1]=-1;de[1]=1; 48 dfs(1); 49 cin>>m; 50 er[0]=1; 51 FOR(i,1,m)er[i]=er[i-1]*2; 52 FOR(i,1,m){ 53 cin>>x>>y;get(x,y,i); 54 } 55 // FOR(i,1,n){ 56 // for(int j=0;j<g[i].size();j++)cout<<g[i][j]<<‘ ‘; 57 // cout<<‘\n‘; 58 // } 59 dp[1][0]=1; 60 FOR(i,2,n){ 61 FOR(j,0,er[m]-1){ 62 dp[i][j]=dp[i][j]+dp[i-1][j]; 63 int t=j; 64 for(int k=0;k<g[i].size();k++)t=t|(er[g[i][k]-1]); 65 dp[i][t]=dp[i][t]+dp[i-1][j]; 66 } 67 } 68 cout<<dp[n][er[m]-1]; 69 RE 0; 70 }
标签:div open turn 转移 int 颜色 条件 view ack
原文地址:https://www.cnblogs.com/njwsf/p/12307664.html