LOJ3274 Chameleon Love

Chameleon Love

In the JOI Zoo, there are \ (2N \) chameleons, numbered \ (1 \ ldots 2N \) . Among them, the sex of \ (N \) chameleon is X, and the sex of other \ (N \) is Y.

Each chameleon has a primary color . The public information about the primary colors is as follows:

  • The primary colors of all chameleons of gender X are different.
  • For each chameleon of sex X, there is a unique chameleon with the same primary color, and the sex is Y.

Now, JOI Zoo is in a season of love. Each chameleon fell in love with another chameleon. The publicly available information about love partners is as follows:

  • Each chameleon is dedicated to the only one of the opposite sex.
  • The color of a chameleon and its partner are different.
  • There are no two chameleons pursuing another chameleon at the same time.

You can convene a part of the chameleon to organize a meeting. For a chameleon participating in a meeting \ (s \) , let \ (t \) be its love object. \ (s \) 's skin color is determined by:

  • If \ (t \) participated in this meeting, the color of \ ( s \) is the original color of \ (t \) .
  • If \ (t \) does not participate in this meeting, then \ (s \) 's skin color is the original color of \ (s \) .

The color of a chameleon can change between different meetings. For a meeting you organized, you can get the number of skin color types of all chameleons on the field.

Since chameleons are also bored, you can only organize \ (20 \, 000 \) meetings at most. At the same time you need to determine which chameleons have the same primary color based on the information you get.
Please write a program to determine all chameleons of the same primary color under the premise of not organizing more than \ (20 \, 000 \) meetings.

\ (2 \ N \ le 500 \)

answer

https://hk-cnyali.com/2020/03/24/"JOISC-2020-Day2 "Chameleon Love-Interaction-Bipartite Diagram /
https://blog.csdn.net/zxyoi_dreamer/article/details/105255333

First specify some marks:

  1. \ (x '\) : the same color point as \ (x \) .

  2. \ (L (x) \) : \ (x \) favorite point.

  3. \ (L ^ {-1} (x) \) : Like \ (x \) .

Consider asking the answers of all sets of size \ (2 \) first , it is not difficult to find that the answer can only be \ (1 \) or \ (2 \) .

The answer is three cases of \ (1 \) : \ (\ {x, x '\}, \ {x, L (x) \}, \ {x, L ^ {-1} (x) \} \ ) . The latter two types will appear if and only if \ (L (x) \ neq L ^ {-1} (x) \) .

We give the point pair \ ((x, y) \) with the answer \ (1 \) connected to an edge, then the degree of each point can only be \ (1 \) or \ (3 \) .

  • If the degree of a point is \ (1 \) , you can directly get the points of the same color.

  • If a point degree is \ (3 \) , set it to \ (x \) , and the three sides are \ ((x, x '), (x, L (x)), (x, L ^ {-1 } (x)) \) . Just ask \ (\ {x, x ', L (x) \}, \ {x, x', L ^ {-1} (x) \}, \ {x, L (x), L ^ { -1} (x) \} \) , these three sets, the answer is \ (2,1,2 \) , then we can get \ (L (x) \) and \ (L ^ {-1 } (L (x)) \) . Finally, we can get the same color point by simply processing it.

In this way, I got the method of asking \ (O (n ^ 2) \) .

Consider optimizing the complexity of the first half.

It is not difficult to find that the graph formed by these edges is a bipartite graph, suppose that the current connecting edges between \ (i \) points and \ (1 \ sim i-1 \) points are to be processed , consider \ (1 \ sim i- 1 \) These points are divided into two independent sets, satisfying that there are no edges inside the set (violent coloring can be processed).

We can judge whether there is an edge according to the nature of the independent set: a set \ (S \) is an independent set if and only if \ (\ texttt {Query} (S) = | S | \) . In other words, the point \ (i \) and an independent set \ (S \) have edges if and only if \ (\ texttt {Query} (\ {S, i \}) \ ne | S | + 1 \) .

So you can find the edge one by one by two points. Complexity \ (O (n \ log n) \) .

CO int N=1e3+10;
vector<int> to[N];
int col[N];
vector<int> node[2];
int L[N],vis[N];

void dfs(int x,int c){
	col[x]=c,node[c].push_back(x);
	for(int y:to[x])if(col[y]==-1) dfs(y,!c);
}
void calc(vector<int> vec,int x){
	while(1){
		vec.push_back(x);
		if(Query(vec)==(int)vec.size()) return;
		vec.pop_back();
		int l=0,r=vec.size()-1,goal=-1;
		while(l<=r){
			int mid=(l+r)>>1;
			vector<int> tmp(vec.begin()+l,vec.begin()+mid+1);
			tmp.push_back(x);
			if(Query(tmp)!=(int)tmp.size()) goal=mid,r=mid-1;
			else l=mid+1;
		}
		if(goal==-1) return;
		int y=vec[goal];
		to[x].push_back(y),to[y].push_back(x);
		vec.erase(vec.begin()+goal);
	}
}
void get_edges(int x){
	node[0].clear(),node[1].clear();
	fill(col,col+x,-1);
	for(int i=1;i<x;++i)if(col[i]==-1) dfs(i,0);
	calc(node[0],x),calc(node[1],x);
}
void Solve(int n){
	for(int i=1;i<=2*n;++i) get_edges(i);
	for(int i=1;i<=2*n;++i)if(to[i].size()==3){
		for(int j=0;j<3;++j){
			vector<int> vec={i};
			for(int k=0;k<3;++k)if(k!=j)
				vec.push_back(to[i][k]);
			if(Query(vec)==1) {L[i]=to[i][j]; break;}
		}
	}
	for(int i=1;i<=2*n;++i){
		if(to[i].size()==1){
			if(!vis[i] and !vis[to[i][0]])
				Answer(i,to[i][0]),vis[i]=vis[to[i][0]]=1;
			continue;
		}
		for(int j=0;j<3;++j){
			if(L[i]==to[i][j] or L[to[i][j]]==i) continue;
			if(!vis[i] and !vis[to[i][j]])
				Answer(i,to[i][j]),vis[i]=vis[to[i][j]]=1;
		}
	}
}

Guess you like

Origin www.cnblogs.com/autoint/p/12676087.html