250 想想就发现规律了。
500 暴力,括号匹配。
1000
给一个f数组,如果i存在,那么f[i]也得存在,问这样的集合有多少种。
先拓扑一下,dp[i] = mul(dp[son]+1)最后环里面的元素的乘积是结果。
#include#include #include #include #include #include #include #include #include #include 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 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; }};