codeforces 558 D Guess Your Way Out! II

题意是这样:

一颗高为h的完美二叉树,根节点为1,标号为i的结点的左右儿子标号分别为2*i,2*i+1

q次操作,i,l,r,ans

ans==0时,代表在第i层,出口的祖先不在[l,r]之间

ans==1时,代表在第i层,出口的祖先在[l,r]之间

若出口(出口一定在叶子上)唯一则输出它的标号,不唯一或无解则分别输出对应的串

我想到的做法很显然,把所有ans==1的子树的叶子区间全部算出来,遍历所有区间,

不断做交集,若不出现交集则无解,于是结果必然是得到一个唯一区间x,出口一定在这里面。

把所有ans==0的子树的叶子区间全部算出来,遍历所有区间,x不断删除与他们相交的部分,

很显然若是最终x的区间只有一个数,那么出口唯一就是这个数,否则有多个解

想到这个很简单。。编码有点麻烦……不过慢慢分治还是能够写对的

#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
struct Itv
{
	ll l,r;
	Itv(){}
	Itv(ll l,ll r)
	{
		this->l=l;
		this->r=r;
	}
	Itv its(Itv one)
	{
		if(one.r<l||one.l>r)
			return Itv(1,0);
		return Itv(max(one.l,l),min(one.r,r));
	}
};
ll fac[60]={1};
Itv cg(ll val,int lv,int h)
{
	return Itv(fac[h-lv]*val,fac[h-lv]*val+fac[h-lv]-1);
}
bool cmp(Itv one,Itv two)
{
	return one.l<two.l;
}
int main()
{
	int h,q;
	cin>>h>>q;
	for(int i=1;i<=h;i++)
		fac[i]=fac[i-1]*2;
	vector<Itv>itv[2];
	while(q--)
	{
		int i,ans;
		ll l,r;
		cin>>i>>l>>r>>ans;
		itv[ans].push_back(Itv(cg(l,i,h).l,cg(r,i,h).r));
	}
	int n=itv[0].size(),m=itv[1].size();
	for(int i=1;i<m;i++)
	{
		itv[1][0]=itv[1][0].its(itv[1][i]);
		if(itv[1][0].l>itv[1][0].r)
		{
			puts("Game cheated!");
			return 0;
		}
	}
	Itv t;
	if(m!=0)
		t=itv[1][0];
	else
		t=Itv(cg(1,1,h).l,cg(1,1,h).r);
	sort(itv[0].begin(),itv[0].end(),cmp);
	ll ans=-1;
	for(int i=0;i<n;i++)
	{
		Itv t1=t.its(itv[0][i]);
		if(t1.l>t1.r)
			continue;
		if(t1.l==t.l&&t1.r==t.r)
		{
			if(ans==-1)
				puts("Game cheated!");
			else
				cout<<ans;
			return 0;
		}
		if(t1.l-t.l>1)
		{
			puts("Data not sufficient!");
			return 0;
		}
		if(t1.l-t.l==1)
		{
			if(ans==-1)
			{
				ans=t.l;
				if(t.r==t1.r)
				{
					cout<<ans;
					return 0;
				}
			}
			else
			{
				puts("Data not sufficient!");
				return 0;
			}
		}
		t.l=t1.r+1;
	}
	if(ans==-1)
	{
		if(t.l==t.r)
			cout<<t.l;
		else
			puts("Data not sufficient!");
	}
	else
		puts("Data not sufficient!");
}

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Amr bought a new video game "Guess Your Way Out! II". The goal of the game is to find an exit from the maze that looks like a perfect binary tree of height h.
The player is initially standing at the root of the tree and the exit from the tree is located at some leaf node.

Let‘s index all the nodes of the tree such that

  • The root is number 1
  • Each internal node i (i?≤?2h?-?1?-?1)
    will have a left child with index = 2i and a right child with index = 2i?+?1

The level of a node is defined as 1 for a root, or 1 +
level of parent of the node otherwise. The vertices of the level h are called leaves. The exit to the maze is located at some leaf
node n, the player doesn‘t know where the exit is so he has to guess his way out!

In the new version of the game the player is allowed to ask questions on the format "Does the ancestor(exit,?i) node
number belong to the range [L,?R]?". Here ancestor(v,?i) is
the ancestor of a node v that located in the level i.
The game will answer with "Yes" or "No" only. The game is designed such that it doesn‘t always answer correctly, and sometimes it cheats to confuse the player!.

Amr asked a lot of questions and got confused by all these answers, so he asked you to help him. Given the questions and its answers, can you identify whether the game is telling contradictory information or not? If the information is not contradictory and
the exit node can be determined uniquely, output its number. If the information is not contradictory, but the exit node isn‘t defined uniquely, output that the number of questions is not sufficient. Otherwise output that the information is contradictory.

Input

The first line contains two integers h,?q (1?≤?h?≤?50, 0?≤?q?≤?105),
the height of the tree and the number of questions respectively.

The next q lines will contain four integers each i,?L,?R,?ans (1?≤?i?≤?h, 2i?-?1?≤?L?≤?R?≤?2i?-?1, ),
representing a question as described in the statement with its answer (ans?=?1 if the answer is "Yes" and ans?=?0 if
the answer is "No").

Output

If the information provided by the game is contradictory output "Game cheated!" without the quotes.

Else if you can uniquely identify the exit to the maze output its index.

Otherwise output "Data not sufficient!" without the quotes.

Sample test(s)

input

3 1
3 4 6 0

output

7

input

4 3
4 10 14 1
3 6 6 0
2 3 3 1

output

14

input

4 2
3 4 6 1
4 12 15 1

output

Data not sufficient!

input

4 2
3 4 5 1
2 3 3 1

output

Game cheated!

Note

Node u is an ancestor of node v if
and only if

  • u is the same node as v,
  • u is the parent of node v,
  • or u is an ancestor of the parent of node v.

In the first sample test there are 4 leaf nodes 4,?5,?6,?7.
The first question says that the node isn‘t in the range [4,?6] so the exit is node number 7.

In the second sample test there are 8 leaf nodes. After the first question the exit is in the range [10,?14].
After the second and the third questions only node number 14 is correct. Check the picture below to fully understand.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 00:16:43

codeforces 558 D Guess Your Way Out! II的相关文章

Codeforces 558(C、D、E)总结

558C 题意:给你n个数,可对每个数进行操作(乘2或者除以2).求最少的操作使得所有的数都相等. 思路 : dp[ t ] 表示所有的数转化到 t 所需的最少操作, vis[ t ] 表示有多少数可以转化成 t . 对于一个数 num , 把它所能到达的数用上述的数组记录下就行了(具体看代码). 注意 : 输入: 3 5 4 4 输出 : 2  (5/2*2=4) #include <iostream> #include <cstdio> #include <cstring

codeforces 558 E A Simple Task

题目大意就是给一个字符串,然后多个操作.每次操作能够把每一段区间的字符进行升序或者降序排序,问终于的字符串是如何的. 做法的话就是用线段树维护区间和 一開始仅仅考虑字符串中字符'a'的情况.如果操作区间[L,R]中有x个'a',那么一次操作后,这x个'a'要么去最左(升序).要么去最右(降序),我们能够建立一颗线段树来维护这种操作,字符'a'出现的位置值为1,否则为0,那么q次操作后,最后值为1的地方填的就是'a'了. 然后,在考虑字符'a'和'b'的情况,操作的情况和上面类似,字符'a'和'b

CodeForces 558 C. Amr and Chemistry &amp;&amp; 51NOD 1483 化学变换(暴力 + 贪心)

传送门 Amr loves Chemistry, and specially doing experiments. He is preparing for a new interesting experiment. Amr has n different types of chemicals. Each chemical i has an initial volume of ai liters. For this experiment, Amr has to mix all the chemic

codeforces 558 C Amr and Chemistry

预处理两个数组: vis[x],有几个数能够变成x num[x],所有数变成x最少需要变化的步数 ans=min(num[x]),vis[x]==n #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector>

区间合并 --- Codeforces 558D : Gess Your Way Out ! II

D. Guess Your Way Out! II Problem's Link: http://codeforces.com/problemset/problem/558/D Mean: 一棵满二叉树,树中某个叶子节点是出口,目的是寻找这个出口.再给定Q个询问的结果,每个结果告诉我们在第i层中(l,r)覆盖的叶结点是否包含出口. analyse: 基本思路:多个区间求交集. 具体实现: 对于每一个询问,把它转化到最底层.并且把不在(l,r)区间的询问改为在(最左边,l-1)和(r+1,最右边)

Codeforces 346C Number Transformation II 构造

题目链接:点击打开链接 = = 990+ms卡过 #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<vector> #include<set> using namespace std; #define N 100010 #define L(x) (x<<1) #define R(x) (x<<

暴力 Codeforces Round #183 (Div. 2) A. Pythagorean Theorem II

题目传送门 1 /* 2 暴力:O (n^2) 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstring> 7 #include <cmath> 8 #include <vector> 9 using namespace std; 10 11 const int MAXN = 1e4 + 10; 12 const int INF = 0x3f3f3f3f; 13 14

Codeforces Gym101257F:Islands II(求割点+思维)

http://codeforces.com/gym/101257/problem/F 题意:给出一个n*m的地图,上面相同数字的代表一个国家,问对于每个国家有多少个国家在它内部(即被包围).例如第一个样例,1包围2,2包围3,所以1包围2和3,2包围3. 思路:昨晚tmk大佬给我们讲了一下这题.对于一个国家,将和它相邻的国家连边,最后形成一个图. 可以发现,如果从随便一个点出发DFS,如果失去了某个点之后,导致整个图不连通了,那么这个点就一定包围了一些国家. 例如下面这个样例: 1 1 1 1

Codeforces Round #428 (Div. 2) D. Winter is here[数论 II]

题目:http://codeforces.com/contest/839/problem/D 题意:找出每种情况使得所有数字gcd不为1,对答案的贡献为gcd值乘数字个数. 题解:因为数字不大,可以哈希出每种数字的个数,然后从后往前,f[i]代表在gcd==i时存在的数字搭配种数.每次计算i时,要减去计算过的种数,所以从后向前计算.每个数字贡献次数为${2}^{sum-1}$(写二进制数的情况可以观察出来),所有数字贡献为$sum*{2}^{sum-1}$ 2次x次方可以先预处理取模出来. 1