hdu6038Function
来源:互联网 发布:mediawiki seo 编辑:程序博客网 时间:2024/04/29 12:34
思路:
看似是数学题。。其实是图论。
我们可以发现他给的函数的约束关系其实是一种递推推导。
对于样例
3 2
1 0 2
0 1
我们把a行的第i个(i从0开始)建一条从i到
这个环是什么意思呢?她代表了一种相互递推的关系,只要在环中的任意一个元素被决定了,环中其余的元素也就都确定了。正因为有这样的性质,所以我们才建图来找出各种环的数量。
tarjan跑两遍分别求出a行中各种环的数量和b行中各种环的数量。
我在这里把这些信息分别存在
然后对于每个非0的
注意环的关系,只有当a中的环的元的个数是b中环的元的个数的整数倍时,我们才能将b中的环放到a中而不引起关系的崩溃。这里采用类似素数筛的方式,直接一遍扫出来。
//b中最多有m元环 sumb数组中保存了aa[i]对应的有多少种取法
for(int i = 1;i <= m;i++){ if(bb[i] == 0) continue; for(int j = i;j <= n;j+=i){ sumb[j] += i*bb[i]; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
再之后,我们需要注意这是在考虑aa[i]为1的情况下的结果,如果aa[i]不为1而是为n,那么我们需要为这n种i元环分别选择一种,即
所以如下:
lli ans = 1;for(lli i = 1;i <= n;i++){ if(aa[i] != 0){//只有当此种环存在时才算 ans *= qp(sumb[i],aa[i]);//quick power 快速幂 ans %= mod; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
ac代码:
#include <iostream>#include <cstdio>#include <queue>#include <string.h>#include <algorithm>#define inf 0x3f3f3f3ftypedef long long int lli;using namespace std;const int maxn = 120000;const int mod = 1e9+7;struct edge{ lli to,v,next;}ed[maxn];lli cnte,head[maxn];void ae(lli x,lli y){ ed[++cnte].to = y; ed[cnte].next = head[x]; head[x] = cnte;}lli aa[maxn],bb[maxn],sumb[maxn],dp[maxn];lli dfn[maxn],low[maxn],vis[maxn],stak[maxn],cntc,cnts,index;void dfs(int u,lli *ss){ dfn[u]=low[u] = ++index; stak[cnts++]=u; vis[u]=1; for(int i = head[u];~i;i=ed[i].next){ lli v = ed[i].to; if(!dfn[v]){ dfs(v,ss); low[u] = min(low[u],low[v]); } else if(vis[v]){ low[u] = min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ cntc++;lli v,cnt = 0; do{ cnt++; v = stak[--cnts]; vis[v] = 0; }while(v!=u); ss[cnt]++; }}lli n,m;void tarjan(lli *ss,lli n){ for(int i = 0;i < n;i++){ if(!dfn[i]) dfs(i,ss); }}inline lli qp(lli a,lli x){ if(a == 0) return 0; lli ans = 1; for(;x;x>>=1){ if(x&1) ans = ans*a % mod; a = a*a % mod; } return ans % mod;}void ini(){ memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); cnte = cntc = cnts = index = 0;}int main(){ int cas = 0; while(~scanf("%I64d%I64d",&n,&m)){ ini(); memset(aa,0,sizeof(aa)); memset(bb,0,sizeof(bb)); memset(sumb,0,sizeof(sumb)); cas++; int temp; for(int i = 0;i < n;i++){ scanf("%d",&temp); ae(i,temp); } tarjan(aa,n); ini(); for(int i = 0;i < m;i++){ scanf("%d",&temp); ae(i,temp); } tarjan(bb,m); for(int i = 1;i <= m;i++){ //类似素数筛 if(bb[i] == 0) continue; for(int j = i;j <= n;j+=i){ sumb[j] += i*bb[i]; } } lli ans = 1; for(lli i = 1;i <= n;i++){ if(aa[i] != 0){ ans *= qp(sumb[i],aa[i]); ans %= mod; } } printf("Case #%d: %lld\n",cas,ans); } return 0;}
#include<cstdio>#include<string>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<map>#include<set>#include<stack>using namespace std;const long long mod=1e9+7;const int maxn=1e5+5;int a[maxn],b[maxn];vector<int>aa;vector<int>bb;bool book[maxn];int main(){freopen("test.txt","r",stdin);int i,j;int n,m;int start;int coun;int cur;int kase=0;while(~scanf("%d %d",&n,&m)){//printf("%d %d\n",n,m);kase++;for(i=0;i<n;i++){scanf("%d",&a[i]);//printf("%d ",a[i]);}for(i=0;i<m;i++){scanf("%d",&b[i]);}memset(book,false,sizeof(book));aa.clear();bb.clear();for(i=0;i<n;i++){if(book[i]==true)continue;book[i]=true;cur=i;coun=1;while(a[cur]!=i){cur=a[cur];book[cur]=true;coun++;}aa.push_back(coun);}memset(book,false,sizeof(book));for(i=0;i<m;i++){if(book[i]==true)continue;book[i]=true;cur=i;coun=1;while(b[cur]!=i){cur=b[cur];book[cur]=true;coun++;}bb.push_back(coun);}long long ans=1;long long tmp;for(i=0;i<aa.size();i++){//printf("%d ",aa[i]);tmp=0;for(j=0;j<bb.size();j++){if(aa[i]%bb[j]==0){tmp+=bb[j];tmp%=mod;}}ans=(ans*tmp)%mod;}//printf("\n");printf("Case #%d: %lld\n",kase,ans);}return 0;}
1- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
阅读全文
0 0
- hdu6038Function
- 重读UNIX网络编程第三章到第十一章笔记整理
- 循序表的(main.c)
- HashMap,HashSet,Hashtable以及TreeMap的原理和区别
- 亚马逊面试被拒
- python中list,tuple,str相互转换
- hdu6038Function
- 如何利用tcpdump来确定外部设备是否连接到服务器?
- 手机号码即时验证:鼠标离开文本框的时候立刻验证
- (8)ajax发送put请求的两种方式
- Heartbeat,LVS ,Keepalived,Ldirectord功能及配置
- hdu6038
- ajax传递参数给springmvc一句话总结
- Tensorflow学习之实现多层感知机
- ThinkPHP多个数据库 配置文件怎么写呀? 特别注意两个数据库的表前缀不同时,怎么写表前缀,两种方法!!