2019牛客暑期多校训练营(第一场)

2019牛客暑期多校训练营 第一场

  • 题目?
  • A.Equivalent Prefixes
    • 题目描述:
    • 输入描述:
    • 输出描述:
    • 解析
  • F.Random Point in Triangle
    • 题目描述
    • 输入描述:
    • 输出描述:
    • 解析
  • J.Fraction Comparision
    • 题目描述
    • 输入描述:
    • 输出描述:
    • 解析

题目?

https://ac.nowcoder.com/acm/contest/881#question

A.Equivalent Prefixes

题目描述:

  Two arrays u u u and v v v each with m distinct elements are called equivalent if and only if R M Q ( u , l , r ) = R M Q ( v , l , r ) RMQ(u,l,r)=RMQ(v,l,r) RMQ(u,l,r)=RMQ(v,l,r) for all 1 ≤ l ≤ r ≤ m 1≤l≤r≤m 1lrm. where R M Q ( w , l , r ) RMQ(w,l,r) RMQ(w,l,r) denotes the index of the minimum element among w l , w l + 1 , … , w r w_l,w_{l+1},…,w_r wl,wl+1,,wr.
  Since the array contains distinct elements, the definition of minimum is unambiguous.
  Bobo has two arrays a a a and b b b each with n n n distinct elements. Find the maximum number p ≤ n p≤n pn where a 1 , a 2 , … , a p {a_1,a_2,…,a_p} a1,a2,,ap and b 1 , b 2 , … , b p {b_1,b_2,…,b_p} b1,b2,,bp are equivalent.

输入描述:

The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains an integer n n n.
The second line contains n integers a 1 , a 2 , … , a n a1,a2,…,an a1,a2,,an.
The third line contains n n n integers b 1 , b 2 , … , b n b1,b2,…,bn b1,b2,,bn.
∗ 1 ≤ n ≤ 1 0 5 *1≤n≤10^5 1n105.
∗ 1 ≤ a i , b i ≤ n *1≤a_i,bi≤n 1ai,bin
∗ { a 1 , a 2 , … , a n } *\{a_1,a_2,…,a_n\} {a1,a2,,an} are distinct.
∗ { b 1 , b 2 , … , b n } *\{b_1,_b2,…,b_n\} {b1,b2,,bn} are distinct.
∗ * The sum of n n n does not exceed 5 × 1 0 5 5×10^5 5×105.

输出描述:

For each test case, print an integer which denotes the result.
示例1
输入
2
1 2
2 1
3
2 1 3
3 1 2
5
3 1 5 2 4
5 2 4 3 1
输出
1
3
4

解析

题目大意:
  当一个数列 { a 1 . . . . . a p } \{a_1.....a_p\} {a1.....ap} { b 1 . . . . . . b p } \{b_1......b_p\} {b1......bp}相同时,当且仅当,在 1 ≤ l ≤ r ≤ p 1≤l≤r≤p 1lrp中,任意的 R M Q ( l , r ) RMQ(l,r) RMQ(l,r)是相同的,这里 R M Q RMQ RMQ取的是区间最小值的索引.如果最小值是 b 1 b_1 b1,那么结果就是 1 1 1.
  在尝试了各种 r m q rmq rmq题目解法后,不断地超时尝试,终于明白,要用单调栈做(==)||
  对于单调栈,我们知道,它可以求某一个数左边第一个比它小的数的位置.
  那么.我们从左到右,建立一个单调递增的单调栈,然后存到 L [ ] L[] L[].这就是两个单调栈.
  随后从左到右比较每一个数的 L [ ] L[] L[],当第 i i i个数不同时,答案便是 i − 1 i-1 i1.
  这里手动模拟一下便能明白了.

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#ifndef NULL
#define NULL 0
#endif

using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int MAXN = 1e5 + 10;

int a[MAXN], b[MAXN],L1[MAXN],L2[MAXN],q[MAXN];
int main()
{
	int n;
	while(cin>>n){
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		for (int i = 1; i <= n; i++)
			cin >> b[i];
		int tail = 0, head = 1;
		for (int i = 1; i <= n; i++) {
			while (tail >= head && a[i] <= a[q[tail]])
				tail--;
			L1[i] = tail < head ? 1 : q[tail] + 1;
			q[++tail] = i;
		}

		tail = 0, head = 1;
		for (int i = 1; i <= n; i++) {
			while (tail >= head && b[i] <= b[q[tail]])
				tail--;
			L2[i] = tail < head ? 1 : q[tail] + 1;
			q[++tail] = i;
		}

		int f = 1;
		for (int i = 1; i <= n; i++)
			if (L1[i] != L2[i]) {
				cout << i - 1 << endl;
				f = 0;
				break;
			}
		if (f)
			cout << n << endl;
	}

	return 0;
}

F.Random Point in Triangle

题目描述

  Bobo has a triangle A B C ABC ABC with A ( x 1 , y 1 ) , B ( x 2 , y 2 ) A(x_1,y_1),B(x_2,y_2) A(x1,y1),B(x2,y2) and C ( x 3 , y 3 ) C(x_3,y_3) C(x3,y3). Picking a point P uniformly in triangle ABC, he wants to know the expectation value E = m a x { S P A B , S P B C , S P C A } E=max\{S_{PAB},S_{PBC},S_{PCA}\} E=max{SPAB,SPBC,SPCA} where S X Y Z S_{XYZ} SXYZ denotes the area of triangle X Y Z XYZ XYZ.Print the value of 36 × E 36×E 36×E. It can be proved that it is always an integer.

输入描述:

The input consists of several test cases and is terminated by end-of-file.
Each test case contains six integers x 1 , y 1 , x 2 , y 2 , x 3 , y 3 x_1,y_1,x_2,y_2,x_3,y_3 x1,y1,x2,y2,x3,y3.

  • ∣ x 1 ∣ , ∣ y 1 ∣ , ∣ x 2 ∣ , ∣ y 2 ∣ , ∣ x 3 ∣ , ∣ y 3 ∣ ≤ 1 0 8 |x_1|,|y_1|,|x_2|,|y_2|,|x_3|,|y_3|≤10^8 x1,y1,x2,y2,x3,y3108
  • There are at most 1 0 5 10^5 105 test cases.

输出描述:

For each test case, print an integer which denotes the result.
示例1
输入
0 0 1 1 2 2
0 0 0 0 1 1
0 0 0 0 0 0
输出
0
0
0

解析

该大佬已经将数学证明讲的灰常清楚了,只要仔细阅读一下,便能理解.
https://blog.csdn.net/ftx456789/article/details/96478804

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#ifndef NULL
#define NULL 0
#endif

using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int MAXN = 1e5 + 10;

int main()
{
    ll x1,y1,x2,y2,x3,y3;
    while(cin>>x1>>y1>>x2>>y2>>x3>>y3){
        cout<<abs((x1*y2+y1*x3+x2*y3)-(x1*y3+y2*x3+y1*x2))*11<<endl;
    }
    return 0;
}

J.Fraction Comparision

题目描述

Bobo has two fractions x a \frac{x}{a} ax and y b \frac{y}{b} by. He wants to compare them. Find the result.

输入描述:

The input consists of several test cases and is terminated by end-of-file.
Each test case contains four integers x , a , y , b x, a, y, b x,a,y,b.

  • 0 ≤ x , y ≤ 1 0 1 8 0≤x,y≤10^18 0x,y1018
  • 1 ≤ a , b ≤ 1 0 9 1≤a,b≤10^9 1a,b109
  • There are at most 1 0 5 10^5 105 test cases.

输出描述:

For each test case, print ′ = ′ '=' = if x a = y b \frac{x}{a}=\frac{y}{b} ax=by. Print ‘ < ‘ `<` < if x a < y b \frac{x}{a}<\frac{y}{b} ax<by. Print ‘ > ‘ `>` > otherwise.
示例1
输入
1 2 1 1
1 1 1 2
1 1 1 1
输出

<
>
=

解析

高精度模板.
非常尴尬的是,我以为拿公约数公倍数能水过去
队里三个人都不会 J a v a Java Java大数
只好掏出自己的板子祭天

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#ifndef NULL
#define NULL 0
#endif
#define MAXN 9999		//MAXN控制每个a[i]内大小
#define DLEN 4		//DLEN控制a[i]中有几位
#define MAXSIZE 5010	//控制数字位数

using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int MAX = 1e5 + 10;
const double PI = acos(-1.0);
//10000

class BigNum {
private:
	int a[MAXSIZE];
	int len;
public:
	BigNum() {
		len = 1;
		memset(a, 0, sizeof(a));
	}
	BigNum(const int);
	BigNum(const char*);
	BigNum(const BigNum &);
	BigNum &operator=(const BigNum &);
	friend istream& operator>>(istream&, BigNum&);
	friend ostream& operator<<(ostream&, BigNum&);
	BigNum operator +(const BigNum &)const;
	BigNum operator -(const BigNum &)const;
	BigNum operator *(const BigNum &)const;
	BigNum operator /(const BigNum &)const;
	BigNum operator /(const int &)const;
	BigNum operator ^(const int &)const;
	long long operator %(const long long &)const;
	bool operator >(const BigNum&i_T)const;
	bool operator ==(const BigNum&i_T)const;
	bool operator >(const int &i_T)const;
	void copy(int str, int end, const BigNum &);
	void print();
};

void BigNum::copy(int str, int end, const BigNum &i_T)
{
	memset(a, 0, sizeof(a));
	for (int i = str; i <= end; i++)
		a[i] = i_T.a[i];
	len = end - str + 1;
	while (a[len - 1] == 0 && len > 1)
		len--;
	cout << (*this) << ' ' << len << endl;
}
//int->BigNum
BigNum::BigNum(const int i_b)
{
	int c, d = i_b;
	len = 0;
	memset(a, 0, sizeof(a));
	while (d > MAXN) {
		c = d - (d / (MAXN + 1))*(MAXN + 1);
		d = d / (MAXN + 1);
		a[len++] = c;
	}
	a[len++] = d;
}
//char->BigNum
BigNum::BigNum(const char *i_s)
{
	int t, k, index, L;
	memset(a, 0, sizeof(a));
	L = strlen(i_s);
	len = L / DLEN;
	if (L%DLEN)
		len++;
	index = 0;
	for (int i = L - 1; i >= 0; i -= DLEN) {
		t = 0;
		k = i - DLEN + 1;
		if (k < 0)
			k = 0;
		for (int j = k; j <= i; j++)
			t = t * 10 + i_s[j] - '0';
		a[index++] = t;
	}
}
//copy
BigNum::BigNum(const BigNum &i_T) :len(i_T.len)
{
	memset(a, 0, sizeof(a));
	for (int i = 0; i < len; i++)
		a[i] = i_T.a[i];
}
//BigNum=BigNum
BigNum&BigNum::operator=(const BigNum&i_n)
{
	len = i_n.len;
	memset(a, 0, sizeof(a));
	for (int i = 0; i < len; i++)
		a[i] = i_n.a[i];
	return *this;
}
//cin>> BigNum
istream& operator >>(istream &in, BigNum &i_b)
{
	char ch[MAXSIZE * DLEN];
	in >> ch;
	int L = strlen(ch), count = 0, sum = 0;
	for (int i = L - 1; i >= 0;) {
		sum = 0;
		int t = 1;
		for (int j = 0; j < DLEN && i >= 0; j++, i--, t *= 10)
			sum += (ch[i] - '0')*t;
		i_b.a[count] = sum;
		count++;
	}
	i_b.len = count++;
	return in;
}
//cout<
ostream& operator <<(ostream& out, BigNum& i_b)
{
	cout << i_b.a[i_b.len - 1];
	for (int i = i_b.len - 2; i >= 0; i--)
		printf("%04d", i_b.a[i]);
	return out;
}

BigNum BigNum::operator/(const BigNum &i_T)const
{
	BigNum t(*this), p(0);
	if (i_T > t)
		return p;
	while (t > i_T) {
		t = t - i_T;
		p = p + 1;
	}
	return p;
}

BigNum BigNum::operator/(const int &i_b)const
{
	BigNum ret;
	int down = 0;
	for (int i = len - 1; i >= 0; i--) {
		ret.a[i] = (a[i] + down * (MAXN + 1)) / i_b;
		down = a[i] + down * (MAXN + 1) - ret.a[i] * i_b;
	}
	ret.len = len;
	while (ret.a[ret.len - 1] == 0 && ret.len > 1)
		ret.len--;
	return ret;
}

long long BigNum::operator%(const long long &i_b)const
{
	long long d = 0;
	for (int i = len - 1; i >= 0; i--)
		d = ((d*MAXN + 1) % i_b + a[i] * 1LL) % i_b;
	return d;
}

BigNum BigNum::operator^(const int &n)const
{
	int i;
	BigNum t, ret(1);
	if (n < 0)
		exit(-1);
	if (n == 0)
		return 1;
	if (n == 1)
		return *this;
	int m = n;
	while (m > 1) {
		t = *this;
		for (i = 1; (i << 1) <= m; i <<= 1)
			t = t * t;
		m -= i;
		ret = ret * t;
		if (m == 1)
			ret = ret * (*this);
	}
	return ret;
}

bool BigNum::operator>(const BigNum &i_T)const
{
	int ln;
	if (len > i_T.len)
		return true;
	else if (len < i_T.len)
		return false;
	else {
		ln = len - 1;
		while (a[ln] == i_T.a[ln] && ln > 0)
			ln--;
		return (ln >= 0 && a[ln] > i_T.a[ln]);
	}
}
bool BigNum::operator==(const BigNum &i_T)const
{
	int ln;
	if (len != i_T.len)
		return false;
	else {
		ln = len - 1;
		while (a[ln] == i_T.a[ln] && ln > 0)
			ln--;
		return (ln == 0 && a[ln] == i_T.a[ln]);
	}
}

bool BigNum::operator>(const int &i_T)const
{
	BigNum b(i_T);
	return *this > b;
}

void BigNum::print()
{
	printf("%d", a[len - 1]);
	for (int i = len - 2; i >= 0; i--)
		printf("%04d", a[i]);
	printf("\n");
}

BigNum BigNum::operator*(const BigNum &i_T)const
{
	BigNum ret;
	int up, i = 0, j = 0, temp, temp1;
	for (i = 0; i < len; i++) {
		up = 0;
		for (j = 0; j < i_T.len; j++) {
			temp = a[i] * i_T.a[j] + ret.a[i + j] + up;
			if (temp > MAXN) {
				temp1 = temp - temp / (MAXN + 1)*(MAXN + 1);
				up = temp / (MAXN + 1);
				ret.a[i + j] = temp1;
			}
			else {
				up = 0;
				ret.a[i + j] = temp;
			}
		}
		if (up != 0)
			ret.a[i + j] = up;
	}
	ret.len = i + j;
	while (ret.a[ret.len - 1] == 0 && ret.len > 1)
		ret.len--;
	return ret;
}

BigNum BigNum::operator+(const BigNum &i_T)const	//BigNum+BigNum
{
	BigNum t(*this);
	int big;
	big = i_T.len > len ? i_T.len : len;
	for (int i = 0; i < big; i++) {
		t.a[i] += i_T.a[i];
		if (t.a[i] > MAXN) {
			t.a[i + 1]++;
			t.a[i] -= MAXN + 1;
		}
	}
	t.len = (t.a[big] != 0) ? big + 1 : big;
	return t;
}

BigNum BigNum::operator-(const BigNum &i_T)const //num - num
{
	int big, j;
	bool flag;
	BigNum t1, t2;
	if (*this > i_T) {
		t1 = *this;
		t2 = i_T;
		flag = 0;
	}
	else {
		t1 = i_T;
		t2 = *this;
		flag = 1;
	}
	big = t1.len;
	for (int i = 0; i < big; i++) {
		if (t1.a[i] < t2.a[i]) {
			j = i + 1;
			while (t1.a[j] == 0)
				j++;
			t1.a[j--]--;
			while (j > i)
				t1.a[j--] += MAXN;
			t1.a[i] += MAXN + 1 - t2.a[i];
		}
		else
			t1.a[i] -= t2.a[i];
	}
	t1.len = big;
	while (t1.a[t1.len - 1] == 0 && t1.len > 1) {
		t1.len--;
		big--;
	}
	if (flag)
		t1.a[big - 1] = 0 - t1.a[big - 1];
	return t1;
}

int main()
{
	BigNum x, y, a, b;
	while (cin >> x >> a >> y >> b) {
		BigNum p = x * b, q = y * a;
		if (p == q)
			printf("=\n");
		else if (p > q)
			printf(">\n");
		else
			printf("<\n");
	}
    return 0;
}

你可能感兴趣的:(QLU_ACM比赛,牛客)