首页 > 代码库 > SRM 628 DIV2

SRM 628 DIV2

250  想想就发现规律了。

500  暴力,括号匹配。

1000

给一个f数组,如果i存在,那么f[i]也得存在,问这样的集合有多少种。

先拓扑一下,dp[i] = mul(dp[son]+1)最后环里面的元素的乘积是结果。

#include <iostream>#include <cstdio>#include <string>#include <algorithm>#include <stdlib.h>#include <vector>#include <cmath>#include <queue>#include <set>#include <stack>using namespace std;#define LL long longint p[51][51],o[51],flag[51],nt[51];LL dp[51];LL temp;void dfs(int x){    flag[x] = 1;    temp *= dp[x];    if(flag[nt[x]] == 1)    return ;    flag[nt[x]] = 1;    dfs(nt[x]);}class InvariantSets{    public :    LL countSets(vector <int> f)    {        int i,j,n,z;        LL ans = 1;        n = f.size();        for(i = 0;i < n;i ++)        {            p[i][f[i]] = 1;            dp[i] = 1;            nt[i] = f[i];            o[f[i]] ++;        }        for(;;)        {            z = 0;            for(i = 0;i < n;i ++)            {                if(o[i] == 0&&!flag[i])                {                    flag[i] = 1;                    z = 1;                    for(j = 0;j < n;j ++)                    {                        if(p[i][j] == 1&&!flag[j])                        {                            dp[j] *= (dp[i] + 1);                            o[j] --;                        }                    }                }            }            if(!z) break;        }        for(i = 0;i < n;i ++)        {            temp = 1;            if(flag[i] == 0)            {                dfs(i);                ans *= (temp+1);            }        }        return ans;    }};
View Code