关于仙人掌的总结
immortalCO的博客
yyb的博客
模板
namespace T{
vector <int> e[maxn * 2];
int tag[maxn * 2];
void adde(int x,int y){
//cout<<x<<" "<<y<<endl;
e[x].PB(y) , e[y].PB(x); }
}
namespace G{
node e[maxn * 2];
int head[maxn],cnt,dfn[maxn],fa[maxn],dfstime,used[maxn];
void adde(int x,int y){
// if ( x < y ) cout<<x<<" "<<y<<endl;
e[++cnt].to = y;
e[cnt].next = head[x];
head[x] = cnt;
}
void dfs(int x){
dfn[x] = ++dfstime;
for(int i = head[x] ; i ; i = e[i].next){
if ( e[i].to == fa[x] ) continue;
if ( dfn[e[i].to] ){
if ( dfn[e[i].to] > dfn[x] ) continue;
//find_circle
++tot , T::tag[tot] = 1;
int z = x;
while ( z != e[i].to ){
T::adde(tot,z);
used[z] = 1;
z = fa[z];
}
T::adde(e[i].to,tot);
}
else{
fa[e[i].to] = x, dfs(e[i].to);
if ( !used[e[i].to] ) used[e[i].to] = 1 , T::adde(x,e[i].to);
}
}
}
}
例题
仙人掌同构
po姐题解
注意环上点是有序的,而树上子树无序。
环有翻转同构,环为根的话还有旋转同构
代码是NEERC 13 C
数据范围大一点
//仙人掌同构数
#include<bits/stdc++.h>
using namespace std;
#define PB push_back
#define lowbit(x) (x&(-x))
#define MP make_pair
#define fi first
#define se second
#define ls(x) (x << 1)
#define rs(x) ((x << 1) | 1)
#define rep(i,l,r) for (register int i = l ; i <= r ; i++)
#define down(i,r,l) for (register int i = r ; i >= l ; i--)
#define fore(i,x) for (int i = head[x] ; i ; i = e[i].next)
#define SZ(v) (int)v.size()
typedef long long ll;
typedef pair <int,int> pr;
const int maxn = 1e6 + 10;
const int inf = 1e8;
const ll MOD = 180143985094819841ll;
//const ll MOD = 1e9 + 7;
const ll C1 = 35224111;
const ll C2 = 33352437;
const ll C3 = 70525121;
ll mul_C2[maxn],inv_C2[maxn];
int prime[maxn],cnt,tag[maxn],mn_p[maxn];
ll mul(ll a,ll b){
// return a * b % MOD;
return (a * b - (ll)(a / (long double)MOD * b + 1e-3)* MOD + MOD) % MOD;
// return (__int128)a * b % MOD;
}
ll power(ll x,ll y){
ll res = 1;
while ( y ) {
if ( y & 1 ) res = mul(res,x);
x = mul(x,x);
y >>= 1;
}
return res;
}
void init(){
ll inv = power(C2,MOD - 2);
mul_C2[0] = inv_C2[0] = 1;
for (int i = 1 ; i < maxn ; i++){
mul_C2[i] = mul(mul_C2[i - 1],C2);
inv_C2[i] = mul(inv_C2[i - 1],inv);
}
for (int i = 2 ; i < maxn ; i++){
if ( !tag[i] ) prime[++cnt] = i , mn_p[i] = i;
for (int j = 1 ; j <= cnt && prime[j] * i < maxn ; j++){
tag[i * prime[j]] = 1;
mn_p[i * prime[j]] = prime[j];
if ( i % prime[j] == 0 ) break;
}
}
}
map <int,int> ans;
int tot,n,m;
struct node{
int next,to,w;
};
void add_to_ans(int num){
while ( num > 1 ){
int c = 0 , cp = mn_p[num];
while ( num % cp == 0 ) num /= cp , c++;
ans[cp] += c;
}
}
namespace T{
vector <int> e[maxn * 2];
int mx[maxn * 2],sz[maxn * 2],tag[maxn * 2];
pr id[2] = {
{
inf,0},{
inf,0}};
void adde(int x,int y){
//cout<<x<<" "<<y<<endl;
e[x].PB(y) , e[y].PB(x); }
void find_g(int x,int fa){
sz[x] = 1;
for (auto y : e[x]){
if ( y == fa ) continue;
find_g(y,x);
sz[x] += sz[y];
mx[x] = max(mx[x],sz[y]);
}
}
ll get_hash_tree(vector <ll> &vec){
ll res = 1240198;
for (auto x : vec){
res = (res + power(C1,x)) % MOD;
}
return res;
}
ll get_hash_cyc(vector <ll> &vec){
ll res = 3982003; ll q = 1;
for (auto x : vec){
q = mul(q,C2);
res = (res + mul(q,power(C3,x))) % MOD;
}
return res;
}
vector <ll> all_cycles(vector <ll> &vec){
vector <ll> item(SZ(vec) * 2);
for (int i = 0 ; i < SZ(vec) ; i++){
item[i] = mul(mul_C2[i +