HDU 6038 Function

来源:互联网 发布:澳洲金融硕士 知乎 编辑:程序博客网 时间:2024/06/14 16:43

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=6038

代码:

#include <cstdio>#include <stack>#include <map>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define met(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3fconst int maxn = 1e5+10;const int mod =1e9+7;typedef long long ll;stack<int> s;vector<int> v[maxn];bool instack[maxn];int dfn[maxn],low[maxn];int belong[maxn];//缩点存储int degree[maxn];int cnt1;//更新int cnt2;//计算有几个满足条件int num1[maxn],num2[maxn];map<int,int> mp2;int length;int n,m;int a[maxn],b[maxn];int ans[maxn];void scc(int x){    dfn[x]=low[x]=cnt1++;    instack[x]=true;    s.push(x);    for(int i=0;i<v[x].size();i++)    {        int y=v[x][i];        if(dfn[y]==-1)        {            scc(y);            low[x]=min(low[x],low[y]);        }        else if(instack[y])        {            low[x]=min(low[x],dfn[y]);        }    }    if(dfn[x]==low[x])    {        int z;        do        {            z=s.top();            s.pop();            instack[z]=false;            belong[z]=cnt2;        }        while(x!=z);        cnt2++;    }}void Tarjan(int x){    while(!s.empty())        s.pop();    met(dfn,-1);    met(low,inf);    met(belong,-1);    met(instack,false);    cnt1=0;    cnt2=0;    for(int i=0;i<x;i++)    {        if(dfn[i]==-1)            scc(i);    }}void slove1(){    Tarjan(n);    met(num1,0);    for(int i=0;i<n;i++)        num1[belong[i]]++;    length=cnt2;}void slove2(){    Tarjan(m);    met(num2,0);    for(int i=0;i<m;i++)        num2[belong[i]]++;    mp2.clear();    for(int i=0;i<cnt2;i++)        mp2[num2[i]]+=num2[i];}int main(){    int id=1;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i=0;i<n;i++)        {            scanf("%d",&a[i]);            v[i].clear();        }        for(int i=0;i<n;i++)            v[a[i]].push_back(i);        slove1();        for(int i=0;i<m;i++)        {            scanf("%d",&b[i]);            v[i].clear();        }        for(int i=0;i<m;i++)            v[b[i]].push_back(i);        slove2();        met(ans,0);        for(int i=0;i<length;i++)        {            for(int j=1;j*j<=num1[i];j++)            {                if(num1[i]%j==0)                {                    ans[i]+=mp2[j];                    if(j*j!=num1[i])                        ans[i]+=mp2[num1[i]/j];                }            }        }        ll sum=1;        for(int i=0;i<length;i++)            sum=(sum*ans[i])%mod;        printf("Case #%d: ",id++);        printf("%lld\n",sum);    }}
原创粉丝点击