BestCoder Round #65

博弈 1002 ZYB‘s Game

题意:中文

分析:假定两个人是绝顶聪明的,一定会采取最优的策略.所以如果选择X的左边的一个点,那么后手应该选择X的右边对称的点,如果没有则必输,否则必胜,然后再分析下就是奇数是1,偶数是0

树状数组+二分(逆序数) 1003 ZYB‘s Premutation

题意:已知每个点前缀逆序对数和,求原排列

分析:可以得知每个点前面有几个比它大,那么用树状数组维护,二分查询从i到n有几个数字,那么答案是i-1

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 5e4 + 5;
int A[N], B[N], a[N];
struct BIT	{
	int c[N], sz;
	void init(int n)	{
		memset (c, 0, sizeof (c));
		sz = n;
	}
	void updata(int i, int x)	{
		while (i <= sz)	{
			c[i] += x;
			i += i & (-i);
		}
	}
	int query(int i)	{
		int ret = 0;
		while (i)	{
			ret += c[i];
			i -= i & (-i);
		}
		return ret;
	}
	int bsearch(int l, int r, int k)	{
		int ret = 0, rr = r;
		while (l <= r)	{
			int mid = (l + r) >> 1;
			int cnt = query (rr) - query (mid);
			if (cnt == k)	{
				ret = mid;	r = mid - 1;
			}
			else if (cnt > k)	l = mid + 1;
			else	r = mid - 1;
		}
		return ret;
	}
}bit;
int n;

int main(void)	{
	int T;	scanf ("%d", &T);
	while (T--)	{
		scanf ("%d", &n);
		for (int i=1; i<=n; ++i)	{
			scanf ("%d", &A[i]);
		}
		B[0] = 0;
		for (int i=2; i<=n; ++i)	{
			B[i] = A[i] - A[i-1];
		}
		bit.init (n);
		for (int i=1; i<=n; ++i)	{
			bit.updata (i, 1);
		}
		for (int i=n; i>=1; --i)	{
			a[i] = bit.bsearch (1, n, B[i]);
			bit.updata (a[i], -1);
		}
		for (int i=1; i<=n; ++i)	{
			printf ("%d%c", a[i], i == n ? ‘\n‘ : ‘ ‘);
		}
	}

	return 0;
}

树形DP 1004 ZYB‘s Tree

题意:一棵树,求所有点它到其他点的距离不大于K的个数的异或和 

分析:dp[u][i] 表示u到子孙的距离为i的点的个数,dp[u][i+1] += dp[v][i].dp2[v][i] 表示v到上面的距离为i的点的个数,dp[v][i+1] += dp2[u][i] + dp[u][i] - dp[v][i-1]

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 5e4 + 5;
int A[N], B[N], a[N];
struct BIT	{
	int c[N], sz;
	void init(int n)	{
		memset (c, 0, sizeof (c));
		sz = n;
	}
	void updata(int i, int x)	{
		while (i <= sz)	{
			c[i] += x;
			i += i & (-i);
		}
	}
	int query(int i)	{
		int ret = 0;
		while (i)	{
			ret += c[i];
			i -= i & (-i);
		}
		return ret;
	}
	int bsearch(int l, int r, int k)	{
		int ret = 0, rr = r;
		while (l <= r)	{
			int mid = (l + r) >> 1;
			int cnt = query (rr) - query (mid);
			if (cnt == k)	{
				ret = mid;	r = mid - 1;
			}
			else if (cnt > k)	l = mid + 1;
			else	r = mid - 1;
		}
		return ret;
	}
}bit;
int n;

int main(void)	{
	int T;	scanf ("%d", &T);
	while (T--)	{
		scanf ("%d", &n);
		for (int i=1; i<=n; ++i)	{
			scanf ("%d", &A[i]);
		}
		B[0] = 0;
		for (int i=2; i<=n; ++i)	{
			B[i] = A[i] - A[i-1];
		}
		bit.init (n);
		for (int i=1; i<=n; ++i)	{
			bit.updata (i, 1);
		}
		for (int i=n; i>=1; --i)	{
			a[i] = bit.bsearch (1, n, B[i]);
			bit.updata (a[i], -1);
		}
		for (int i=1; i<=n; ++i)	{
			printf ("%d%c", a[i], i == n ? ‘\n‘ : ‘ ‘);
		}
	}

	return 0;
}
时间: 2024-10-14 02:28:21

BestCoder Round #65的相关文章

BestCoder Round #65 (ZYB&#39;s Game)

ZYB's Game Accepts: 672 Submissions: 1207 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description ZYBZYBZYB played a game named NumberBombNumber BombNumberBomb with his classmates in hiking:a host keeps a

Bestcoder round #65 &amp;&amp; hdu 5592 ZYB&#39;s Premutation 线段树

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 175    Accepted Submission(s): 74 Problem Description ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutat

Bestcoder round #65 &amp;&amp; hdu 5593 ZYB&#39;s Tree 树形dp

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 354    Accepted Submission(s): 100 Problem Description ZYB has a tree with N nodes,now he wants you to solve the numbers of nodes distanced no m

hdu5592/BestCoder Round #65 树状数组寻找第K大

ZYB's Premutation Memory Limit: 131072/131072 K (Java/Others) 问题描述 ZYBZYB有一个排列PP,但他只记得PP中每个前缀区间的逆序对数,现在他要求你还原这个排列. (i,j)(i < j)(i,j)(i<j)被称为一对逆序对当且仅当A_i>A_jA?i??>A?j?? 输入描述 第一行一个整数TT表示数据组数. 接下来每组数据: 第一行一个正整数NN,描述排列的长度. 第二行NN个正整数A_iA?i??,描述前缀区间

BestCoder Round #65 B C D || HDU 5591 5592 5593

B 题意:ZYB在远足中,和同学们玩了一个“数字炸弹”游戏:由主持人心里想一个在[1,N][1,N]中的数字XX,然后玩家们轮流猜一个数字,如果一个玩家恰好猜中XX则算负,否则主持人将告诉全场的人当前的数和XX比是偏大还是偏小,然后猜测的范围就会相应减小,一开始的范围是[1,N][1,N].每个玩家只能在合法的范围中猜测. 现在假设只有两个人在玩这个游戏,并且两个人都已经知道了最后的XX,若两个人都采取最优策略.求X \in [1,N]X∈[1,N]中是后手胜利的XX数量. 思路: 当n为奇数时

BestCoder Round #65 hdu5592 5593 5594

hdu5592 - ZYB's Premutation http://acm.hdu.edu.cn/showproblem.php?pid=5592 对于一个X=a[i]-a[i-1],它可以表示为原排列第i个位置的数,在它前面有X个比它大的数,也就是说在1到i的区间内第i个数为该区间内第X+1大的数 那么可以考虑倒着求出原排列:对于最后一个数,令k=a[n]-a[n-1],最后一个数就是k+1:而对于倒数第二个数,令k'=a[n-1]-a[n-2],则该位置的答案为从1到n中除去k,第k'+1

BestCoder Round #4 前两题 hdu 4931 4932

第一题太水了.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int a[6]; 7 int main(){ 8 int cas; 9 scanf( "%d", &cas ); 10 while( cas-- ){ 11 for( int i = 0; i <

BestCoder Round #50 (div.2)

题目传送:BestCoder Round #50 (div.2) BC感觉越做越无语了 1001.Distribution money AC代码: #include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <queue> #include <stack> #include <bitset> #

从lca到树链剖分 bestcoder round#45 1003

bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或),高手就不这么做了,直接树链剖分.为什么不能用lca,因为如果有树退化成链,那么每次询问的复杂度是O(n), 那么q次询问的时间复杂度是O(qn) 什么是树链剖分呢? 就是把树的边分成轻链和重链 http://blogsina.com.cn/s/blog_6974c8b20100zc61.htmlh