首页 > 其他分享 >Codeforces Round 864 (Div. 2)

Codeforces Round 864 (Div. 2)

时间:2023-04-12 16:01:00浏览次数:44  
标签:sz CI return int 864 Codeforces inline Div include

Preface

周六的最后一战,感觉脑子确实有点混沌了一个C题好多细节没考虑好心态差点爆炸

最后还好20min速切了D稳了手排名,不然已经回到蓝名了

感觉最近打比赛老是犯一些很离谱的失误,题目老是想不清楚导致好几场没法在比赛时写掉Div2的E了

嘛说白了还是练得少了,多刷题解决一切问题的说


A. Li Hua and Maze

不难发现如果这两个点中有一个在角落上,那么只要堵住它临近的两个格子即可

否则如果有一个在边上,那么只要堵住它临近的三个格子即可

否则我们肯定可以用四个格子堵住其中任意一个

#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
int t,n,m,X1,Y1,X2,Y2;
inline bool corner(CI x,CI y)
{
	return (x==1&&y==1)||(x==1&&y==m)||(x==n&&y==1)||(x==n&&y==m);
}
inline bool edge(CI x,CI y)
{
	return x==1||x==n||y==1||y==m;
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		scanf("%d%d%d%d%d%d",&n,&m,&X1,&Y1,&X2,&Y2);
		if (corner(X1,Y1)||corner(X2,Y2)) puts("2"); else
		if (edge(X1,Y1)||edge(X2,Y2)) puts("3"); else puts("4");
	}
	return 0;
}

B. Li Hua and Pattern

首先把所有翻转后对应的位置上的颜色比较一下,如果不一样就至少要花费一次操作

然后都执行完后看下如果\(k<0\)则显然无解,否则要满足\(2|k\)才能通过修改某对位置来满足要求

但是还要注意一个情况,当\(n\)为奇数时\(k\)为奇数也是合法的,因为我们可以把多余的操作全部扔在最中间的那个点上,刚开始没考虑到还WA了一发

#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
const int N=1005;
int t,n,k,a[N][N];
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i,j; for (scanf("%d%d",&n,&k),i=1;i<=n;++i)
		for (j=1;j<=n;++j) scanf("%d",&a[i][j]);
		for (i=1;i<=n;++i) for (j=1;j<=n;++j)
		if (a[i][j]!=a[n-i+1][n-j+1]) a[i][j]^=1,--k;
		if (k<0) { puts("NO"); continue; }
		if (k%2==0) { puts("YES"); continue; }
		if (n&1) puts("YES"); else puts("NO");
	}
	return 0;
}

C. Li Hua and Chess

思路很简单,但是我就是猪脑过载想不清楚,前前后后卡了快1h真是菜得飞起

一个很naive的想法就是我们尽量询问角落上的点,这样每次询问就能确定目标点在两条线段上

通过连续的两次询问可以很容易地把答案锁定在某个线段上,然后这样在第三次询问时我们可以询问线段的一个端点来确定位置了

说起来轻巧但是要注意很多Corner Cases,比如考虑\(n,m\)的大小关系,相交的形态等等,具体看代码吧

#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
int t,n,m;
inline int ask(CI x,CI y)
{
	printf("? %d %d\n",x,y); fflush(stdout);
	int z; scanf("%d",&z); return z;
}
inline void answer(CI x,CI y)
{
	printf("! %d %d\n",x,y); fflush(stdout);
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		scanf("%d%d",&n,&m); int A,B,C;
		if (n>m)
		{
			A=ask(1,1); B=ask(n,1);
			if (1+A!=n-B)
			{
				if (A<B) answer(n-B,1+A); else if (A>B) answer(1+A,1+B); else
				{
					C=ask(n-B,1+A); answer(n-B+C,1+A);
				}
			} else
			{
				C=ask(1+A,1); answer(1+A,1+C);
			}
		} else
		{
			A=ask(1,1); B=ask(1,m);
			if (1+A!=m-B) 
			{
				if (A<B) answer(1+A,m-B); else if (A>B) answer(1+B,1+A); else
				{
					C=ask(1+A,m-B); answer(1+A,m-B+C);
				}
			} else
			{
				C=ask(1,1+A); answer(1+C,1+A);
			}
		}
	}
	return 0;
}

D. Li Hua and Tree

早知道先写D题了,就是个模拟+STL的裸题

首先我们很容易想到旋转操作只会影响当前点、当前点的重儿子、当前点的父亲这三个点的信息

很显然可以直接用set维护下每个点的重儿子信息,然后手玩一下转移过程别搞错细节就行

#include<cstdio>
#include<iostream>
#include<set>
#include<vector>
#define int long long
#define RI register int
#define CI const int&
using namespace std;
const int N=100005;
struct Data
{
	int s,id;
	inline Data(CI S=0,CI ID=0)
	{
		s=S; id=ID;
	}
	friend inline bool operator < (const Data& A,const Data& B)
	{
		return A.s!=B.s?A.s>B.s:A.id<B.id;
	}
}; multiset <Data> hp[N]; int n,m,a[N],sz[N],sum[N],fa[N],x,y; vector <int> v[N];
inline void DFS(CI now=1,CI f=0)
{
	fa[now]=f; sum[now]=a[now]; sz[now]=1;
	for (int to:v[now]) if (to!=f)
	{
		DFS(to,now); sum[now]+=sum[to]; sz[now]+=sz[to];
		hp[now].insert(Data(sz[to],to));
	}
}
signed main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i; for (scanf("%lld%lld",&n,&m),i=1;i<=n;++i) scanf("%lld",&a[i]);
	for (i=1;i<n;++i) scanf("%lld%lld",&x,&y),v[x].push_back(y),v[y].push_back(x);
	for (DFS(),i=1;i<=m;++i)
	{
		if (scanf("%lld%lld",&x,&y),x==1) printf("%lld\n",sum[y]); else
		{
			if (hp[y].empty()) continue;
			int son=hp[y].begin()->id; hp[y].erase(hp[y].begin());
			hp[fa[y]].erase(hp[fa[y]].find(Data(sz[y],y)));
			hp[son].insert(Data(sz[y]-sz[son],y));
			hp[fa[y]].insert(Data(sz[y],son));
			int tf=fa[y]; fa[y]=son; fa[son]=tf;
			int ts=sz[y]; sz[y]=ts-sz[son]; sz[son]=ts;
			int A=sum[y],B=sum[son]; sum[y]=A-B; sum[son]=A;
		}
	}
	return 0;
}

E. Li Hua and Array

什么大缝合题,数论+树论+数据结构大综合了属于是,不过每个涉及得都很浅所以还是很好想的

首先很自然可以想到我们对于每个数\(x(x>1)\),连一条\(\phi(x)\to x\)的边,这样就形成了一颗树

然后询问就可以转化为求一个区间内所有点到它们的公共LCA的距离之和

很容易想到我们求出每个点的深度后就转化为区间求和和区间求LCA的问题了,但区间所有点的LCA乍一看感觉有点难处理的说

其实方法也很简单,我们找出区间内DFS序最小和最大的点,则它们的LCA就是区间内所有点的LCA,这个画个图看一下还是很好理解的说

然后考虑修改,这个就是经典套路了,由于取\(\phi\)在\(\log\)次后就会变成\(1\),所以我们可以直接暴力搞,势能分析一下复杂度是对的

当然这个性质还给我们带来一个好处,由于树高是\(\log\)级别的,所以我们不需要在写求LCA的算法了,直接暴力跳即可

总复杂度\(O(n\log A_i)\)

#include<cstdio>
#include<iostream>
#include<set>
#define RI register int
#define CI const int&
using namespace std;
const int N=100005,M=5000000;
int n,m,a[N],tp,l,r,pri[M+5],cnt,phi[M+5],seq[M+5],dfn[M+5],dep[M+5],idx;
bool vis[M+5]; set <int> s[M+5];
inline void init(CI n)
{
	phi[1]=1; for (RI i=2,j;i<=n;++i)
	{
		if (!vis[i]) pri[++cnt]=i,phi[i]=i-1;
		for (j=1;j<=cnt&&i*pri[j]<=n;++j)
		if (vis[i*pri[j]]=1,i%pri[j]) phi[i*pri[j]]=phi[i]*(pri[j]-1);
		else { phi[i*pri[j]]=phi[i]*pri[j]; break; }
	}
}
inline void DFS(CI now=1)
{
	seq[dfn[now]=++idx]=now; dep[now]=dep[phi[now]]+1; for (int to:s[now]) DFS(to);
}
inline int getLCA(int x,int y)
{
	if (dep[x]<dep[y]) swap(x,y);
	while (dep[x]>dep[y]) x=phi[x];
	if (x==y) return x;
	while (phi[x]!=phi[y]) x=phi[x],y=phi[y];
	return phi[x];
}
class Segment_Tree
{
	private:
		struct segment
		{
			long long sum; int mi,mx;
			inline segment(const long long SUM=0,CI MI=1e9,CI MX=0)
			{
				sum=SUM; mi=MI; mx=MX;
			}
		}node[N<<2];
		#define S(now) node[now].sum
		#define MI(now) node[now].mi
		#define MX(now) node[now].mx
		#define TN CI now=1,CI l=1,CI r=n
		#define LS now<<1,l,mid
		#define RS now<<1|1,mid+1,r
		inline void pushup(CI now)
		{
			S(now)=S(now<<1)+S(now<<1|1);
			MI(now)=min(MI(now<<1),MI(now<<1|1));
			MX(now)=max(MX(now<<1),MX(now<<1|1));
		}
	public:
		inline void build(TN)
		{
			if (l==r) return (void)(node[now]=(segment){dep[a[l]],dfn[a[l]],dfn[a[l]]});
			int mid=l+r>>1; build(LS); build(RS); pushup(now);
		}
		inline void modify(CI beg,CI end,TN)
		{
			if (beg<=l&&r<=end)
			{
				if (MX(now)==1) return;
				if (l==r) return (void)(a[l]=phi[a[l]],node[now]=(segment){dep[a[l]],dfn[a[l]],dfn[a[l]]});
			}
			int mid=l+r>>1; if (beg<=mid) modify(beg,end,LS); if (end>mid) modify(beg,end,RS); pushup(now);
		}
		inline long long getsum(CI beg,CI end,TN)
		{
			if (beg<=l&&r<=end) return S(now); int mid=l+r>>1; long long ret=0;
			if (beg<=mid) ret+=getsum(beg,end,LS); if (end>mid) ret+=getsum(beg,end,RS); return ret;
		}
		inline int getmin(CI beg,CI end,TN)
		{
			if (beg<=l&&r<=end) return MI(now); int mid=l+r>>1,ret=1e9;
			if (beg<=mid) ret=min(ret,getmin(beg,end,LS)); if (end>mid) ret=min(ret,getmin(beg,end,RS)); return ret;
		}
		inline int getmax(CI beg,CI end,TN)
		{
			if (beg<=l&&r<=end) return MX(now); int mid=l+r>>1,ret=0;
			if (beg<=mid) ret=max(ret,getmax(beg,end,LS)); if (end>mid) ret=max(ret,getmax(beg,end,RS)); return ret;
		}
		#undef S
		#undef MI
		#undef MX
		#undef TN
		#undef LS
		#undef RS
}SEG;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i; for (scanf("%d%d",&n,&m),init(M),i=1;i<=n;++i)
	{
		scanf("%d",&a[i]); int tmp=a[i];
		while (tmp>1) s[phi[tmp]].insert(tmp),tmp=phi[tmp];
	}
	for (DFS(),SEG.build(),i=1;i<=m;++i)
	if (scanf("%d%d%d",&tp,&l,&r),tp==1) SEG.modify(l,r); else
	{
		int lca=getLCA(seq[SEG.getmin(l,r)],seq[SEG.getmax(l,r)]);
		printf("%lld\n",SEG.getsum(l,r)-1LL*dep[lca]*(r-l+1));
	}
	return 0;
}

Postscript

这场比赛是国人出的吧都是Li Hua的说,自从高中毕业后都以为再也不会见到了结果在CF上见到了

标签:sz,CI,return,int,864,Codeforces,inline,Div,include
From: https://www.cnblogs.com/cjjsb/p/17310102.html

相关文章

  • UVa 11498 Division of Nlogonia (water ver.)
    11498-DivisionofNlogoniaTimelimit:1.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2493TheProblemAftercenturiesofhostilitiesandskirmishesbetweenthefour......
  • Codeforces Round 862 (Div. 2)
    CodeforcesRound862(Div.2)Date:04/07/2023Link:Dashboard-CodeforcesRound862(Div.2)-CodeforcesA|WeNeedtheZeroBrief:给定非负整数序列,求一个\(x\),使得序列每个元素异或\(x\)后再全部异或起来的结果为\(0\).没有输出\(-1\).Data:\(T\leq1e3,......
  • Codeforces Round 864 (Div. 2) 题解
    A.LiHuaandMaze题目保证了两个点的哈密顿距离至少为\(2\),所以他们不会相邻。只要有点在角上答案就是\(2\),在边上但不在角上就是\(3\),否则就是\(4\)。#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#includ......
  • Divisors UVA - 294
    求区间[L,R]的整数中哪一个的正约数最多。  一个数因数分解后,它的约数Cnt=(a[j]+1)的乘积,j是每个因数的个数 #include<iostream>#include<cstring>#include<cmath>#include<algorithm>usingnamespacestd;constintM=1e5+30;#defineintlonglo......
  • Codeforces Round 864 (Div. 2)
    CodeforcesRound864(Div.2)题目链接CodeforcesRound864(Div.2)A题这个题是一个思维题稍微想一下应该就可以解决.1.我们可以发现如果点(x,y)位于正方形的四个角上把这个点围起来需要两次操作2.如果点(x,y)在正方形的4条边上,需要3个操作将其其围起来3.如果点(x,y)在......
  • 洛谷与 Codeforces 的难度评级
    为了比较CF与洛谷的题目难度评级,我写了一个爬虫,爬取了CF题目在源站和洛谷中的难度,并进行比较。这里先给出两者的换算:洛谷入门普及-普及/提高-普及+/提高提高+/省选-省选/NOI-NOI/NOI+/CTSCCF800900-11001200-15001600-19002000-23002400-29003000-350......
  • Codeforces Round 677 (Div. 3) E. Two Round Dances(数论)
    https://codeforces.com/contest/1433/problem/E题目大意:n个人(n是偶数)跳了两轮舞,每轮舞正好有n/2个人。你的任务是找出n个人跳两轮舞的方法,如果每轮舞正好由n/2个人组成。每个人都应该属于这两种圆舞中的一种。人相同位置不同也算是同一种方案。input2output1input......
  • Codeforces Round 864 (Div. 2)
    题解报告基本的一些理解和问题都在注释中A:LiHuaandMaze就是判断把其中一个点围起来所需要的最小的格子,考虑下边界的情况就行了#include<bits/stdc++.h>usingnamespacestd;intmain(void){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);intT;c......
  • Codeforces Round 864 (Div. 2) E. Li Hua and Array
    CodeforcesRound864(Div.2E.LiHuaandArray)(暴力修改线段树+lca和数论的结合)Exampleinput5481637215234113234output1021Solution首先你得知道什么是欧拉函数我们\(O(n)\)求出\([1,5e6]\)范围内的每个数的欧拉函数后可以求一下最大的跳......
  • cf-div2-856c
    题目链接:https://codeforces.com/contest/1816/problem/C我是傻逼,否了自己的第一直觉。。。思路:构造方法:以最后一个值的数值\(x\)为基准,把所有的的数字(除第一个)调整为\(x\)。以n的奇偶性分为两种情况。当n为奇数时:\(第一个数字y小于等于x,构造成功。否则就除了第一个数字外......