首页 > 其他分享 >AtCoder Regular Contest 153(持续更新)

AtCoder Regular Contest 153(持续更新)

时间:2023-01-16 21:58:11浏览次数:46  
标签:AtCoder 153 CODE Contest int sum freopen include RI

Preface

B题粗糙了改了好几个版本,最后索性从头理了一遍思路才过

然后剩下40min想C又歪了(构造题精通的被动消失了),还剩25min的时候忍不住了看LPL去了

话说现在的ARC感觉和以前的AGC难度相当啊,不过也许是没有陈指导教我我什么都做不来


A - AABCDDEFE

就是用类似康托展开的思路来算每一部分的值,直接看代码吧

#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
int n;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i; scanf("%d",&n); --n;
	int p=n/100000,q=n%100000; for (i=1;i<=2;++i) putchar(p+'1');
	int pp=q/1000,qq=q%1000; putchar(pp/10+'0'); putchar(pp%10+'0');
	int ppp=qq/100,qqq=qq%100; for (i=1;i<=2;++i) putchar(ppp+'0');
	int pppp=qqq/10,qqqq=qqq%10;
	putchar(pppp+'0'); putchar(qqqq+'0'); putchar(pppp+'0');
	return 0;
}

B - Grid Rotations

话说我比赛时的做法怪的很,还找不到方法解释,结果现在写Editorial的时候就想到个很好的解释法

先讲比赛时想的,首先容易发现行和列的情况可以分别独立考虑,我们只要求出每一行在操作后变成哪一行即可,记为\(r_i\)

考虑对行的某次旋转操作\(a_i\),观察到前半部分每次对换的位置的下标之和为\(a_i+1\),后半部分每次对换的下标之和为\(a_i+1+H\),这两个在模\(H\)意义下时一样的

因此对于某个行\(r_i\)转变后的值就是\(a_i+1-r_i\)在模\(H\)意义下的值,因此我们根据环的性质可以发现最后\(r_i\)一定可以形成一个环的形态

当然上面的说法不是很明显,我们考虑换一种方法理解

我们考虑让第\(1\)行和第\(n\)行相连,在行之间形成一个环,同时考虑一次旋转操作不会影响每一行相邻的行是什么

举个例子,比如\(H=4\)时,原来初始时环的形态是\([1,2,3,4]\),在进行操作\(a_i=3\)后变成\([3,2,1,4]\)

不难发现每个数相邻的两个数都没有变,变化的只是\(1\)所在的位置和与其相邻的\(2\)的方向而已

因此我们只要维护每次旋转后\(1\)的位置即可,列的情况完全相同

#include<cstdio>
#include<iostream>
#include<vector>
#include<cctype>
#define RI register int
#define CI const int&
using namespace std;
const int N=500005;
int n,m,q,a[N],b[N],h[N],w[N],d; vector <char> A[N];
inline char getch(void)
{
	char ch; while (ch=getchar(),isspace(ch)); return ch;
}
inline int Nxt(int x,CI T)
{
	x+=d; if (x<=0) x+=T; if (x>T) x-=T; return x;
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i,j; for (scanf("%d%d",&n,&m),i=1;i<=n;++i)
	for (A[i].resize(m+1),j=1;j<=m;++j) A[i][j]=getch();
	int sf_h=1,sf_w=1; for (scanf("%d",&q),i=1;i<=q;++i)
	{
		scanf("%d%d",&a[i],&b[i]); ++a[i]; ++b[i];
		if ((sf_h=a[i]-sf_h)<=0) sf_h+=n;
		if ((sf_w=b[i]-sf_w)<=0) sf_w+=m;
	}
	d=q&1?-1:1; int ct; h[sf_h]=1; w[sf_w]=1;
	for (ct=1,i=Nxt(sf_h,n);i!=sf_h;i=Nxt(i,n)) h[i]=++ct;
	for (ct=1,i=Nxt(sf_w,m);i!=sf_w;i=Nxt(i,m)) w[i]=++ct;
	for (i=1;i<=n;++i,putchar('\n')) for (j=1;j<=m;++j) putchar(A[h[i]][w[j]]);
	return 0;
}

C - ± Increasing Sequence

原来是个如此simple的构造题,给我CPU干过载了

我们不妨先进行一次很naive的尝试,令\(x_i=i\),并统计出此时\(\sum_{i=1}^N A_ix_i\)的值\(sum\)

若\(sum=0\)则显然直接输出即可,否则我们求出\(A_i\)的前缀和数组\(pfx_i\),并分类讨论:

  • 若\(sum>0\),我们考虑找到第一个\(pfx_i=1\)的位置\(pos\),然后我们发现每当我们将\(x_j,j\in[1,pos]\)减\(1\)时,最后的\(\sum_{i=1}^N A_ix_i\)就会恰好减\(1\),因此我们直接让\(x_j,j\in[1,pos]\)减去\(sum\)即可
  • 若\(sum<0\),类似上面的思路,我们设第一个\(pfx=-1\)的位置为\(pos\),直接让\(x_j,j\in[1,pos]\)加上\(sum\)即可

考虑到\(sum\)的范围是\(n^2\)级别的,因此可以满足\(|x_i|\le 10^{12}\)的限制

#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
const int N=200005;
int n,a[N],pfx[N]; long long ans[N],sum;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i,j; for (scanf("%d",&n),i=1;i<=n;++i)
	scanf("%d",&a[i]),pfx[i]=pfx[i-1]+a[i],ans[i]=i,sum+=1LL*ans[i]*a[i];
	bool flag=0; if (sum==0) flag=1;
	else if (sum>0)
	{
		for (i=1;i<=n;++i) if (pfx[i]==1)
		{
			for (j=1;j<=i;++j) ans[j]-=sum; flag=1; break;
		}
	} else
	{
		for (i=1;i<=n;++i) if (pfx[i]==-1)
		{
			for (j=1;j<=i;++j) ans[j]+=sum; flag=1; break;
		}
	}
	if (flag) for (puts("Yes"),i=1;i<=n;++i) printf("%lld ",ans[i]);
	else puts("No"); return 0;
}

标签:AtCoder,153,CODE,Contest,int,sum,freopen,include,RI
From: https://www.cnblogs.com/cjjsb/p/17056375.html

相关文章

  • AtCoder Beginner Contest 285
    AtCoderBeginnerContest285题目来源A-EdgeChecker2题意判断一个完全二叉树,两个节点是否直接相连分析\(a=b*2或者a=b*2+1(a<b)a、b\)相连voidsolve(){ ......
  • AtCoder Beginner Contest 285 ——D
    题目:D-ChangeUsernames(atcoder.jp)题解:在所有的s[i]和t[i]之间连接一条有向边,由s[i]指向t[i],连接完之后可以发现,会形成若干条链或者环,如果出现了环那么一定不可以实......
  • 题解 ARC153B【Grid Rotations】
    一次操作是把四个子矩形分别旋转\(180^\circ\)。不难发现,可以横纵坐标分别考虑,则该操作变为横坐标的两段区间分别翻转、纵坐标的两段区间分别翻转。区间翻转操作、最后输......
  • Atcoder ABC285 赛后总结
    A—EdgeChecker2传送门题目大意给你一棵树,输入两个\(1-15\)的数\(a,b\),求\(a\)是否是\(b\)老爹父亲这颗树如图:题目解法超级无敌暴力法(wu一种最最最简......
  • AtCoder Beginner Contest 285 题解
    比赛链接:https://atcoder.jp/contests/abc285总体来说不算难。A-C略。\(D\)因为起点终点不同,起点之间、终点之间两两不同,所以有环的情况是错的,其他都是对的。写起来的......
  • AtCoder Beginner Contest 285 解题报告
    AtCoderBeginnerContest285解题报告\(\text{DaiRuiChen007}\)ContestLinkA.EdgeChecker2假设\(a\geb\),当且仅当\(\left\lfloor\dfraca2\right\rfloor=b\)......
  • AtCoder Beginner Contest 285 D - Change Usernames(拓扑排序)
    这题想到可以用map容器将string与一个端点下标对应,再建一个有向图,将问题转换成判断一个有向图是否有环赛后补题网上搜如何判断图是否有环,学到了拓扑排序拓扑排序是什么......
  • Atcoder ARC 061 题解
    C-ManyFormulas题意​ 给出一个长度为10的由数字组成的字符串,你可以把'+'插入到任意位置,将字符串分割,形成一个算式。你有很多分割的方案,现在你需要将所有出现的算式的......
  • AtCoder Beginner Contest 285
    A-EdgeChecker2(abc285a)题目大意给定如下一棵树。给定\(a,b(a<b)\),问两者是否有连边。解题思路观察数可发现其为二叉树,两者有连边当且仅当\(b=2a\)或\(b=2a......
  • Atcoder Regular Contest ARC 153 A B C D 题解
    点我看题A-AABCDDEFE一个beautifulnumber是形如这样的:\(S1S1S3S4S5S5S7S8S7\)。如果选定了\(S1\),后面的数有100000种选法,所以先求出答案的\(S1\)。假设现在我们要求出......