给定
考虑卡片之间的联系,显然若一个数在同一张卡牌的正反面那么这张卡牌必须选择,否则无法凑齐一个排列,反之这个数一定会在两张卡牌中出现,且这两张卡牌一定至少有一张被选择,否则依然无法凑齐一个排列,这个很好理解。
于是我们考虑一些对于这种题的一般的套路,可以尝试建图,对于本题不难想到,我们将一张卡牌作为一个点,将这个点向卡牌上存在的数的另一次出现所在的卡牌连一条边。抽象地说,对于一个数所在的两张(或一张)卡牌位置
不难想到这样会形成多个环,每一个环代表着其中几张卡牌,同时这些卡牌上的数在环内一定每个数都出现了两遍,如排列
同时发现不同环的方案数,只跟环的长度有关,于是我们考虑令
于是考虑并查集维护好每个环的大小,
xxxxxxxxxx78123
45678910
11using namespace std;12using namespace __gnu_pbds;13
14mt19937 rnd(random_device{}());15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}16bool rnddd(int x){return rndd(1, 100) <= x;}17
18typedef unsigned int uint;19typedef unsigned long long unll;20typedef long long ll;21typedef long double ld;22
2324
25template< typename T = int >26inline T read(void);27
28int N;29int P[210000], Q[210000];30int cnt[210000];31int pos[210000][2];32int f[210000];33bool vis[210000];34int ans(1);35
36class UnionFind{37private:38public:39 int fa[210000];40 int siz[210000];41 UnionFind(void){for(int i = 1; i <= 201000; ++i)fa[i] = i, siz[i] = 1;}42 int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}43 void Union(int origin, int son){44 if(Find(origin) == Find(son))return;45 siz[Find(origin)] += siz[Find(son)], fa[Find(son)] = Find(origin);46 }47}uf;48
49int main(){50 N = read();51 f[1] = 1, f[2] = 3;52 for(int i = 3; i <= N; ++i)f[i] = (ll)(f[i - 1] + f[i - 2]) % MOD;53 for(int i = 1; i <= N; ++i)P[i] = read(), pos[P[i]][cnt[P[i]]++] = i;54 for(int i = 1; i <= N; ++i)Q[i] = read(), pos[Q[i]][cnt[Q[i]]++] = i;55 for(int i = 1; i <= N; ++i)56 uf.Union(i, pos[P[i]][0] ^ pos[P[i]][1] ^ i),57 uf.Union(i, pos[Q[i]][0] ^ pos[Q[i]][1] ^ i);58 for(int i = 1; i <= N; ++i)if(uf.Find(i) == i)ans = (ll)ans * f[uf.siz[uf.Find(i)]] % MOD;59 printf("%d\n", ans);60 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);61 return 0;62}63
64template < typename T >65inline T read(void){66 T ret(0);67 short flag(1);68 char c = getchar();69 while(c != '-' && !isdigit(c))c = getchar();70 if(c == '-')flag = -1, c = getchar();71 while(isdigit(c)){72 ret *= 10;73 ret += int(c - '0');74 c = getchar();75 }76 ret *= flag;77 return ret;78}update-2022_10_25 初稿