hdu6038Function

来源:互联网 发布:mediawiki seo 编辑:程序博客网 时间:2024/04/29 12:34

思路:

看似是数学题。。其实是图论。
我们可以发现他给的函数的约束关系其实是一种递推推导。
对于样例
3 2
1 0 2
0 1
我们把a行的第i个(i从0开始)建一条从i到 ai 的边,那么对于这个样例我们得到了一个二元环和一个一元环,对b行进行相应的操作,我们得到了两个一元环。(我这里的二元环即代表由两个元素组成的环)

这个环是什么意思呢?她代表了一种相互递推的关系,只要在环中的任意一个元素被决定了,环中其余的元素也就都确定了。正因为有这样的性质,所以我们才建图来找出各种环的数量。

tarjan跑两遍分别求出a行中各种环的数量和b行中各种环的数量。
我在这里把这些信息分别存在 aa[n]bb[m] 中。其中 aa[i] 表示i元环的数量为 aa[i] 个。

然后对于每个非0的 aa[i] ,我们需要算出有多少 bb[i] 能够放进去。比如 aa[3]=1bb[1]=1
bb[3]=1 那么我们应该得到的答案即: 1*bb[1] + 3*bb[3] (此处算的是每个aa[i]的取的种数,最后答案需要将这些相乘)

注意环的关系,只有当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元环分别选择一种,即 sumb[i]n
所以如下:

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