This is the final chapter, permanent missing.
Main idea of the title:
There are N cards, each card has numbers on both sides, ranging from 1 to 2 N. Find the least number of inversions, so that each card has different numbers on the upward side, and find out the number of solutions to achieve this effect. (multi-test, each card faces upward at the beginning, with unsolvable output "-1-1")
Solutions:
20% data (N<=20)
Direct search is enough.
100% data (N<=1*105)
Search complexity is not allowed. We try to abstract this problem.
If the number on the card is abstracted as a point and the card is abstracted as a edge, the problem will be transformed into:
For a digraph, some edges are flipped so that the entrance of each point is less than or equal to 1.
First connect the edges, we find that the whole map has at most 2N points, but only N edges. This means that the connectivity of graphs is very poor. Graphs are divided into many interconnection blocks. Then we discuss each interconnection block by classification.
Let the number of edges of the connected block be e and the number of points be v.
If e < v, the whole picture must have no solution. According to the drawer principle, at least one point has a degree of entry greater than 1.
If e=v, the graph is a base ring tree, and the vertex penetration on the ring cannot be zero, because the vertex on the ring must be pointed at by the point on the other ring. If the condition is satisfied, it must be a base-extroverted tree.
If e=v+1, the graph is a tree, and it can be used twice to find the minimum cost required.
For the first time, a point is selected for dfs, which is updated by the son to the father. If the DFS passes through an opposite side, add 1 to the f array. If the DFS is a base ring tree, it also needs to record an unused side to prevent the path of the second DFS from being different from that of the first one. Then, for the second time, the father updates the son. If it passes through the opposite side, add 1 to the G array and subtract 1 from it. The g and f arrays are equal at the root of the search tree.
In the second dfs, the g value of each node is pressed into a vector, and then sort it. The first is the minimum, and the number of solutions is the same as the minimum.
Finally multiply.
Single complexity O (NlogN)
Code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<algorithm> 6 #define LL long long 7 using namespace std; 8 const int N=100010; 9 const LL mod=998244353; 10 int t,n,m=1,mv=0,me=0,cnt=0,tot=0,top=0,start,endd,bridge; 11 int fi[N<<1],g[N<<1],f[N<<1]; 12 bool v[N<<1],vis[N<<1]; 13 struct edge{ 14 int u,v,ne; 15 }e[N<<1]; 16 vector<int> gg; 17 void add(int x,int y) 18 { 19 e[++m].u=x; 20 e[m].v=y; 21 e[m].ne=fi[x]; 22 fi[x]=m; 23 } 24 int read() 25 { 26 int s=0; 27 char c=getchar(); 28 while(c<'0'||c>'9') c=getchar(); 29 while(c>='0'&&c<='9'){ 30 s=(s<<3)+(s<<1)+c-'0'; 31 c=getchar(); 32 } 33 return s; 34 } 35 void clean() 36 { 37 memset(fi,0,sizeof(fi)); 38 memset(e,0,sizeof(e)); 39 memset(f,0,sizeof(f)); 40 memset(g,0,sizeof(g)); 41 memset(v,false,sizeof(v)); 42 memset(vis,false,sizeof(vis)); 43 m=1;top=tot=cnt=0; 44 } 45 void dfs(int x) 46 { 47 v[x]=true;mv++; 48 for(int i=fi[x];i!=0;i=e[i].ne){ 49 int y=e[i].v; 50 me++; 51 if(v[y]) continue; 52 dfs(y); 53 } 54 } 55 void dfs1(int x,int p) 56 { 57 vis[x]=true; 58 for(int i=fi[x];i!=0;i=e[i].ne){ 59 int y=e[i].v; 60 if(y==p) continue; 61 if(vis[y]){ 62 start=x;endd=y;bridge=i; 63 } 64 else{ 65 dfs1(y,x); 66 f[x]+=f[y]+(i&1); 67 } 68 } 69 } 70 void dfs2(int x,int p) 71 { 72 gg.push_back(g[x]); 73 for(int i=fi[x];i!=0;i=e[i].ne){ 74 int y=e[i].v; 75 if(y==p||i==bridge||i==(bridge^1)) continue; 76 g[y]=g[x]+((i&1)==1?-1:1); 77 dfs2(y,x); 78 } 79 } 80 int main() 81 { 82 t=read(); 83 while(t--) 84 { 85 clean(); 86 n=read(); 87 for(int i=1;i<=n;i++){ 88 int x=read(),y=read(); 89 add(y,x);add(x,y); 90 } 91 int flag=0; 92 for(int i=1;i<=2*n;i++){ 93 if(!v[i]){ 94 mv=me=0; 95 dfs(i); 96 if(me/2>mv){ 97 printf("-1 -1\n"); 98 flag=1;break; 99 } 100 } 101 } 102 if(flag==1) continue; 103 int ans1=0;LL ans2=1; 104 for(int i=1;i<=2*n;i++){ 105 if(!vis[i]){ 106 LL num=0;start=endd=bridge=0; 107 gg.clear(); 108 dfs1(i,0); 109 g[i]=f[i]; 110 dfs2(i,0); 111 if(bridge==0){ 112 sort(gg.begin(),gg.end()); 113 ans1+=gg[0]; 114 for(int j=0;j<gg.size();j++){ 115 if(gg[j]!=gg[0]) break; 116 num++; 117 } 118 } 119 else{ 120 bridge&=1; 121 if(g[start]+(bridge^1)==g[endd]+bridge) num=2; 122 else num=1; 123 ans1+=min(g[start]+(bridge^1),g[endd]+bridge); 124 } 125 ans2=ans2*num%mod; 126 } 127 } 128 printf("%d %lld\n",ans1,ans2); 129 } 130 return 0; 131 }