AtCoder Beginner Contest 367 A ~ F(无D题)题解

AtCoder Beginner Contest 367 A ~ F( ̸ \not D)

几天前就已经vp过了,但是忘写题解了

今天才想起来

痛,早知道这么简单,我就不在家里摆烂了

A.Shout Everyday

罚了好几发,我打比赛一如既往的抽象

问题陈述

在 AtCoder 王国,居民们每天都要在 A A A 点大声喊出他们对章鱼烧的热爱。

住在 AtCoder 王国的高桥每天 B B B 点睡觉, C C C 点起床( 24 24 24 小时钟)。他醒着的时候可以喊出对章鱼烧的爱,但睡着的时候却不能。判断他是否每天都能喊出对章鱼烧的爱。这里,一天有 24 24 24 小时,他的睡眠时间小于 24 24 24 小时。

如果 B < C B < C B<C,那么 0 ∼ B − 1 ⋀ C + 1 ∼ 24 0 \sim B - 1 \bigwedge C + 1 \sim 24 0B1C+124 是清醒的
如果 B > C B > C B>C,那么 C + 1 ∼ B − 1 C + 1 \sim B - 1 C+1B1 是清醒的

AC-code:

#include
using namespace std;

int rd() {
	int x = 0, w = 1;
	char ch = 0;
	while (ch < '0' || ch > '9') {
		if (ch == '-') w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + (ch - '0');
		ch = getchar();
	}
	return x * w;
}

void wt(int x) {
	static int sta[35];
	int f = 1;
	if(x < 0) f = -1,x *= f;
	int top = 0;
	do {
		sta[top++] = x % 10, x /= 10;
	} while (x);
	if(f == -1) putchar('-');
	while (top) putchar(sta[--top] + 48);
}

signed main() {

	int a = rd(),b = rd(),c = rd();
	if(b < c) {
		if(a < b || a > c) puts("Yes");
		else puts("No");
	}else {
		if(a < b && a > c) puts("Yes");
		else puts("No");
	}

	return 0;
}
B. Cut .0

赛时唐完了,jiangly好像也是用string(乐

问题陈述

一个实数 X X X 的小数点后第三位。

请在下列条件下打印实数 X X X

  • 小数部分不能有尾数 “0”。
  • 小数点后不能有多余的尾数。

这道题如果用 string ,那么恭喜你走了弯路!

这道题直接 cin >> 即可

#include
using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	double x;
	cin>>x;
	cout<<x;
	return 0;
}
C.Enumerate Sequences
问题陈述

按升序排列,打印所有满足以下条件的长度为 N N N 的整数序列。

  • i i i 个元素介于 1 1 1 R i R_i Ri (含)之间。
  • 所有元素之和是 K K K 的倍数。

什么是序列的词典顺序?如果下面的 1. 或 2. 成立,则序列 A = ( A 1 , … , A ∣ A ∣ ) A = (A _ 1, \ldots, A _ {|A|}) A=(A1,,AA) 在词法上**小于 B = ( B 1 , … , B ∣ B ∣ ) B = (B _ 1, \ldots, B _ {|B|}) B=(B1,,BB)

  1. ∣ A ∣ < ∣ B ∣ |A|<|B| A<B ( A 1 , … , A ∣ A ∣ ) = ( B 1 , … , B ∣ A ∣ ) (A _ {1},\ldots,A _ {|A|}) = (B _ 1,\ldots,B _ {|A|}) (A1,,AA)=(B1,,BA)
  2. 存在一个整数 1 ≤ i ≤ min ⁡ ∣ A ∣ , ∣ B ∣ 1\leq i\leq \min\\{|A|,|B|\\} 1iminA,B ,且以下两个条件均为真:
  • ( A 1 , … , A i − 1 ) = ( B 1 , … , B i − 1 ) (A _ {1},\ldots,A _ {i-1}) = (B _ 1,\ldots,B _ {i-1}) (A1,,Ai1)=(B1,,Bi1)
  • A i < B i A _ i < B _ i Ai<Bi

数据范围这么小!

这道题是直接暴搜!

AC-code:

#include
using namespace std;

int rd() {
	int x = 0, w = 1;
	char ch = 0;
	while (ch < '0' || ch > '9') {
		if (ch == '-') w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + (ch - '0');
		ch = getchar();
	}
	return x * w;
}

void wt(int x) {
	static int sta[35];
	int f = 1;
	if(x < 0) f = -1,x *= f;
	int top = 0;
	do {
		sta[top++] = x % 10, x /= 10;
	} while (x);
	if(f == -1) putchar('-');
	while (top) putchar(sta[--top] + 48);
}
const int N = 10;
int n,k;
int a[N],b[N];

void dfs(int now,int s) {
	if(now == n + 1) {
		if(s % k == 0) {
			for(int i = 1;i<=n;i++)	wt(b[i]),putchar(' ');
			putchar('\n');
		}
		return;
	}
	for(int i = 1;i<=a[now];i++) {
		b[now] = i;
		dfs(now + 1,s + i);
	}
}

signed main() {
	n = rd(),k = rd();
	for(int i = 1;i<=n;i++) a[i] = rd();
	dfs(1,0);
	return 0;
}
E.Permute K times
问题陈述

给你一个长度为 N N N 的序列 X X X ,其中每个元素都在 1 1 1 N N N 之间(包括首尾两个元素),以及一个长度为 N N N 的序列 A A A
打印在 A A A 上执行以下操作 K K K 次的结果。

  • A A A 替换为 B B B ,使得 B i = A X i B _ i = A _ {X _ i} Bi=AXi .

X i X_i Xi 看做 i i i 的父亲,其实这道题就是基环树上求 k t h kth kth 父亲

直接考虑倍增

AC-code:

#include
using namespace std;
#define int long long
int rd() {
	int x = 0, w = 1;
	char ch = 0;
	while (ch < '0' || ch > '9') {
		if (ch == '-') w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + (ch - '0');
		ch = getchar();
	}
	return x * w;
}

void wt(int x) {
	static int sta[35];
	int f = 1;
	if(x < 0) f = -1,x *= f;
	int top = 0;
	do {
		sta[top++] = x % 10, x /= 10;
	} while (x);
	if(f == -1) putchar('-');
	while (top) putchar(sta[--top] + 48);
}
const int N = 2e5+5;
int n,k,a[N],b[N];
int f[60][N];

signed main() {

	n = rd(),k = rd();
	for(int i = 1;i<=n;i++) f[0][i] = rd();
	for(int i = 1;i<=n;i++) a[i] = rd();
	for(int i = 1;i<=n;i++) b[i] = i;
	for(int j = 1;j<60;j++)
		for(int i = 1;i<=n;i++)	
			f[j][i] = f[j - 1][f[j - 1][i]];
	for(int j = 59;j >= 0;j--)
		if((k >> j) & 1) 
			for(int i = 1;i<=n;i++)
				b[i] = f[j][b[i]];
	for(int i = 1;i<=n;i++)
		wt(a[b[i]]),putchar(' ');
	return 0;
}
F.Rearrange Query
问题陈述

给你长度为 N N N 的正整数序列: A = ( A 1 , A 2 , … , A N ) A=(A _ 1,A _ 2,\ldots,A _ N) A=(A1,A2,,AN) B = ( B 1 , B 2 , … , B N ) B=(B _ 1,B _ 2,\ldots,B _ N) B=(B1,B2,,BN) .

给你 Q Q Q 个查询,让你按顺序处理。下面将对 i i i -th 查询进行解释。

  • 给定正整数 l i , r i , L i , R i l _ i,r _ i,L _ i,R _ i li,ri,Li,Ri 。如果可以重新排列子序列 ( A l i , A l i + 1 , … , A r i ) (A _ {l _ i},A _ {l _ i+1},\ldots,A _ {r _ i}) (Ali,Ali+1,,Ari) 以匹配子序列 ( B L i , B L i + 1 , … , B R i ) (B _ {L _ i},B _ {L _ i+1},\ldots,B _ {R _ i}) (BLi,BLi+1,,BRi) ,则打印 “是”,否则打印 “否”。

查询区间多重集元素是否相同?

仙人指路:P3792

可以Hash 做,但是我不会

考虑正确性高的做法,维护 n n n 次方和

用线段树维护 ∑ l r x 1 ∼ 3 \sum_{l}^r x^{1\sim 3} lrx13

我赛时维护到了 7 7 7 次方(比较唐)

#include
using namespace std;
#define int unsigned long long
int rd() {
	int x = 0, w = 1;
	char ch = 0;
	while (ch < '0' || ch > '9') {
		if (ch == '-') w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + (ch - '0');
		ch = getchar();
	}
	return x * w;
}

void wt(int x) {
	static int sta[35];
	int f = 1;
	if(x < 0) f = -1,x *= f;
	int top = 0;
	do {
		sta[top++] = x % 10, x /= 10;
	} while (x);
	if(f == -1) putchar('-');
	while (top) putchar(sta[--top] + 48);
}
const int N =2e5+5;
int n,q;
struct sgt{
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((pl + pr) >> 1)
int o[N];
int s[N<<2],s2[N<<2],s3[N<<2],mx[N<<2],mn[N<<2],s4[N<<2],s5[N<<2],s6[N<<2],s7[N<<2];

void push_up(int p) {
	mx[p] = max(mx[ls],mx[rs]);
	mn[p] = min(mn[ls],mn[rs]);
	s[p] = s[ls] + s[rs];
	s2[p] = s2[ls] + s2[rs];
	s3[p] = s3[ls] + s3[rs];
	s4[p] = s4[ls] + s4[rs];
	s5[p] = s5[ls] + s5[rs];
	s6[p] = s6[ls] + s6[rs];
	s7[p] = s7[ls] + s7[rs];
}

void build(int p,int pl,int pr) {
	if(pl == pr) {
		mx[p] = mn[p] = s[p] = o[pl];
		s2[p] = o[pl] * o[pl];
		s3[p] = o[pl] * o[pl] * o[pl];
		s4[p] = o[pl] * o[pl] * o[pl]* o[pl];
		s5[p] = o[pl] * o[pl] * o[pl]* o[pl]* o[pl];
		s6[p] = o[pl] * o[pl] * o[pl]* o[pl]* o[pl]* o[pl];
		s7[p] = o[pl] * o[pl] * o[pl]* o[pl]* o[pl]* o[pl]* o[pl];
		return;
	}
	build(ls,pl,mid);
	build(rs,mid+1,pr);
	push_up(p);
}

int query_s(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return s[p];
	int re = 0;
	if(l <= mid) re += query_s(ls,pl,mid,l,r);
	if(r > mid) re += query_s(rs,mid+1,pr,l,r);
	return re;
}

int query_s2(int p,int pl,int pr,int l,int r){
	if(l <= pl && pr <= r) return s2[p];
	int re = 0;
	if(l <= mid) re += query_s2(ls,pl,mid,l,r);
	if(r > mid) re += query_s2(rs,mid+1,pr,l,r);
	return re;
}

int query_s3(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return s3[p];
	int re = 0;
	if(l <= mid) re += query_s3(ls,pl,mid,l,r);
	if(r > mid) re += query_s3(rs,mid+1,pr,l,r);
	return re;
}
int query_s4(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return s4[p];
	int re = 0;
	if(l <= mid) re += query_s4(ls,pl,mid,l,r);
	if(r > mid) re += query_s4(rs,mid+1,pr,l,r);
	return re;
}
int query_s5(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return s5[p];
	int re = 0;
	if(l <= mid) re += query_s5(ls,pl,mid,l,r);
	if(r > mid) re += query_s5(rs,mid+1,pr,l,r);
	return re;
}
int query_s6(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return s6[p];
	int re = 0;
	if(l <= mid) re += query_s6(ls,pl,mid,l,r);
	if(r > mid) re += query_s6(rs,mid+1,pr,l,r);
	return re;
}
int query_s7(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return s7[p];
	int re = 0;
	if(l <= mid) re += query_s7(ls,pl,mid,l,r);
	if(r > mid) re += query_s7(rs,mid+1,pr,l,r);
	return re;
}

int query_mx(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return mx[p];
	int re = 0;
	if(l <= mid) re = max(re,query_mx(ls,pl,mid,l,r));
	if(r > mid) re = max(re,query_mx(rs,mid+1,pr,l,r));
	return re;
}

int query_mn(int p,int pl,int pr,int l,int r) {
	if(l <= pl && pr <= r) return mn[p];
	int re = INT_MAX;
	if(l <= mid) re = min(re,query_mn(ls,pl,mid,l,r));
	if(r > mid) re = min(re,query_mn(rs,mid+1,pr,l,r));
	return re;
}

}A,B;

signed main() {

	n = rd(),q = rd();
	for(int i = 1;i<=n;i++) A.o[i] = rd();
	for(int i = 1;i<=n;i++) B.o[i] = rd();
	A.build(1,1,n);B.build(1,1,n);
	while(q--) {
		int l = rd(),r = rd(),L = rd(),R = rd();
		bool flag1 = (A.query_s(1,1,n,l,r) == B.query_s(1,1,n,L,R));
		bool flag2 = A.query_s2(1,1,n,l,r) == B.query_s2(1,1,n,L,R);
		bool flag3 = A.query_s3(1,1,n,l,r) == B.query_s3(1,1,n,L,R);
		bool flag4 = A.query_mn(1,1,n,l,r) == B.query_mn(1,1,n,L,R);
		bool flag5 = A.query_mx(1,1,n,l,r) == B.query_mx(1,1,n,L,R);
		bool flag6 = A.query_s4(1,1,n,l,r) == B.query_s4(1,1,n,L,R);
		bool flag7 = A.query_s5(1,1,n,l,r) == B.query_s5(1,1,n,L,R);
		bool flag8 = A.query_s6(1,1,n,l,r) == B.query_s6(1,1,n,L,R);
		bool flag9 = A.query_s7(1,1,n,l,r) == B.query_s7(1,1,n,L,R);
		if(flag1 && flag2 && flag3 && flag4 && flag5&& flag6&& flag7&& flag8&& flag9) puts("Yes");
		else puts("No");
	}

	return 0;
}

你可能感兴趣的:(题解,竞赛,信息竞赛,c++,算法,Atcoder,题解)