首页 > 其他分享 >Codeforces Round #956 (Div. 2) and ByteRace 2024

Codeforces Round #956 (Div. 2) and ByteRace 2024

时间:2024-07-09 18:30:15浏览次数:9  
标签:typedef int Codeforces long 956 2024 include RI define

Preface

连着好几天因为熬夜看LOL比赛导致白天精神萎靡,都没精力VP了

而且明天就要开始统一训练了,趁着最后一天补一下前两天因为看比赛没打的这场吧

这场只能说是战术正确,想了会E没啥思路就马上转头去把F写了,后面回头慢慢想E也想出来了,最后极限2h14min出了E


A. Array Divisibility

签到,直接令 \(a_i=i\) 就能得到一组合法解

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=105;
int t,n;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; for (scanf("%d",&n),i=1;i<=n;++i)
		printf("%d%c",i," \n"[i==n]);
	}
	return 0;
}

B. Corner Twist

不难发现操作可以在保证每行每列的和关于 \(3\) 取模下不变的前提下任意修改每个位置的值,因此比较每行每列的和即可

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=505;
int t,n,m; char a[N][N],b[N][N];
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i,j; scanf("%d%d",&n,&m); bool flag=1;
		for (i=1;i<=n;++i) scanf("%s",a[i]+1);
		for (i=1;i<=n;++i) scanf("%s",b[i]+1);
		for (i=1;i<=n&&flag;++i)
		{
			int suma=0,sumb=0;
			for (j=1;j<=m;++j) suma+=a[i][j]-'0',sumb+=b[i][j]-'0';
			if (suma%3!=sumb%3) flag=0;
		}
		for (j=1;j<=m&&flag;++j)
		{
			int suma=0,sumb=0;
			for (i=1;i<=n;++i) suma+=a[i][j]-'0',sumb+=b[i][j]-'0';
			if (suma%3!=sumb%3) flag=0;
		}
		puts(flag?"YES":"NO");
	}
	return 0;
}

C. Have Your Cake and Eat It Too

首先 \(3!\) 枚举下从前往后的每一段分别是由哪个人拿走

通过 two pointers 枚举中间那段的极小的合法区间,然后检验前后缀是否合法即可

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define int long long
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=200005;
int t,n,x,lim,pfx[3][N];
signed main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%lld",&t);t;--t)
	{
		RI i,j; for (scanf("%lld",&n),j=0;j<3;++j)
		for (i=1;i<=n;++i) scanf("%lld",&x),pfx[j][i]=pfx[j][i-1]+x;
		lim=(pfx[0][n]+2)/3;
		auto solve=[&](CI a,CI b,CI c)
		{
			auto sum=[&](CI id,CI l,CI r)
			{
				if (l>r) return 0LL;
				return pfx[id][r]-pfx[id][l-1];
			};
			for (RI i=1,j=1;i<=n;++i)
			{
				while (j<=i&&sum(b,j,i)>=lim) ++j;
				if (j>1) --j;
				if (sum(b,j,i)>=lim&&sum(a,1,j-1)>=lim&&sum(c,i+1,n)>=lim)
				{
					pi ans[3];
					ans[a]=pi(1,j-1); ans[b]=pi(j,i); ans[c]=pi(i+1,n);
					for (RI k=0;k<3;++k) printf("%d %d ",ans[k].fi,ans[k].se);
					putchar('\n'); return 1;
				}
			}
			return 0;
		};
		if (solve(0,1,2)) continue;
		if (solve(0,2,1)) continue;
		if (solve(1,0,2)) continue;
		if (solve(1,2,0)) continue;
		if (solve(2,0,1)) continue;
		if (solve(2,1,0)) continue;
		puts("-1");
	}
	return 0;
}

D. Swap Dilemma

首先判掉 \(a,b\) 对应的多重集不同的情况,然后看到交换我们就想到逆序对

由于每次交换两个位置序列的逆序对的奇偶性一定会发生改变,因此大力猜测一手有解的充要条件是 \(a,b\) 的逆序对数量奇偶性相同

必要性上面已经说明;充分性可以考虑只交换相邻两个元素,我们可以对一个序列进行重复操作来保持其不变,让另一个序列向其变化即可

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=200005;
int t,n,a[N],b[N],ca[N],cb[N];
class Tree_Array
{
	private:
		int bit[N];
	public:
		#define lowbit(x) (x&-x)
		inline int get(RI x,int ret=0)
		{
			for (;x<=200000;x+=lowbit(x)) ret+=bit[x]; return ret;
		}
		inline void add(RI x,CI y)
		{
			for (;x;x-=lowbit(x)) bit[x]+=y;
		}
		#undef lowbit
}BIT;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; scanf("%d",&n); bool flag=1;
		for (i=1;i<=n;++i) scanf("%d",&a[i]),++ca[a[i]];
		for (i=1;i<=n;++i) scanf("%d",&b[i]),++cb[b[i]];
		for (i=1;i<=n;++i) if (ca[a[i]]!=cb[a[i]]) { flag=0; break; }
		for (i=1;i<=n;++i) ca[a[i]]=cb[b[i]]=0;
		if (!flag) { puts("NO"); continue; }
		LL suma=0; for (i=1;i<=n;++i)
		suma+=BIT.get(a[i]+1),BIT.add(a[i],1);
		for (i=1;i<=n;++i) BIT.add(a[i],-1);
		LL sumb=0; for (i=1;i<=n;++i)
		sumb+=BIT.get(b[i]+1),BIT.add(b[i],1);
		for (i=1;i<=n;++i) BIT.add(b[i],-1);
		puts(suma%2==sumb%2?"YES":"NO");
	}
	return 0;
}

E. I Love Balls

首先我们只要知道了每个人拿到的特殊球和普通球的个数就可以根据期望的线性性来计算答案了

同时不难发现先手拿到的普通球个数就是 \(\lceil \frac{n-k}{2} \rceil\),难点在于计算先手拿到多少个特殊球

有一个naive的DP想法,即设 \(f_{i,j}\) 表示在有 \(i\) 个特殊球,\(j\) 个普通球的局面下,先手拿到的特殊球数量的期望,转移很显然:

\[f_{i,j}=\frac{i}{i+j}\times (1+f_{i-1,j})+\frac{j}{i+j}\times (i-f_{i,j-1}) \]

直接这么做是 \(O(n^2)\) 的,考虑用更好的方法来计数

不妨从宏观的角度来思考,我们把 \(n\) 个球按照拿走的顺序构成一个排列,则 \(n-k\) 个特殊球把序列分成了 \(n-k+1\) 个间隔

每个特殊球在每个间隔中的概率是相同的,而先手会拿走其中 \(\lceil \frac{n-k+1}{2} \rceil\) 个间隔中的特殊球,因此先手拿走的球数量的期望为:

\[k\times \frac{\lceil \frac{n-k+1}{2} \rceil}{n-k+1} \]

剩下的就很好处理了,总复杂度 \(O(n)\)

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int mod=1e9+7;
int t,n,k,x;
inline int sum(CI x,CI y)
{
	return x+y>=mod?x+y-mod:x+y;
}
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
	for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; scanf("%d%d",&n,&k); int s1=0,s2=0;
		for (i=1;i<=k;++i) scanf("%d",&x),s1=sum(s1,x);
		for (i=1;i<=n-k;++i) scanf("%d",&x),s2=sum(s2,x);
		int ans1=sum(1LL*k*((n-k+2)/2)%mod*quick_pow(n-k+1)%mod*s1%mod*quick_pow(k)%mod,1LL*((n-k+1)/2)*s2%mod*quick_pow(n-k)%mod);
		printf("%d %d\n",ans1,(sum(s1,s2)-ans1+mod)%mod);
	}
	return 0;
}

F. array-value

求第 \(k\) 大值一眼想到二分答案 \(x\),转化为求贡献 \(\le x\) 的区间数量

考虑对于某个右端点 \(i\),令 \(p_i\) 表示最大的 \(j<i\),满足 \(a_j\oplus a_i\le x\)

这样我们只要把 \(\{p\}\) 数组做前缀最大值后,再把所有位置的值加起来就是合法的区间数量了

而要求 \(p_i\) 也很简单,\(a_j\oplus a_i\le x\) 是非常经典的用 0/1Trie 处理的套路了:即考虑在 \(x\) 为 \(1\) 的那些二进制位上保持前缀不变,然后让 \(a_j\oplus a_i\) 这一位取 \(0\),后面的就可以随便取了

0/1Trie 中每个节点维护子树内最靠右的坐标值即可,总复杂度 \(O(n\log^2 a_i)\)

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=100005;
int t,n,a[N],rt; LL k;
class Trie
{
	private:
		int ch[N*30][2],mxp[N*30],idx;
	public:
		inline void clear(void)
		{
			for (RI i=1;i<=idx;++i) ch[i][0]=ch[i][1]=mxp[i]=0; rt=idx=0;
		}
		inline void insert(int& now,CI x,CI pos,CI d=29)
		{
			if (!now) now=++idx;
			mxp[now]=max(mxp[now],pos);
			if (d==-1) return;
			insert(ch[now][(x>>d)&1],x,pos,d-1);
		}
		inline int query(CI now,CI x,CI lim,CI d=29)
		{
			if (!now||d==-1) return 0;
			if ((lim>>d)&1) return max(mxp[ch[now][(x>>d)&1]],query(ch[now][((x>>d)&1)^1],x,lim,d-1));
			else return query(ch[now][(x>>d)&1],x,lim,d-1);
		}
}T;
inline LL calc(CI lim)
{
	LL sum=0; int pos=0; T.clear();
	for (RI i=1;i<=n;++i)
	{
		pos=max(pos,T.query(rt,a[i],lim+1));
		sum+=pos; T.insert(rt,a[i],i);
	}
	return sum;
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; for (scanf("%d%lld",&n,&k),i=1;i<=n;++i) scanf("%d",&a[i]);
		int l=0,r=1<<30,mid,ret; while (l<=r)
		if (calc(mid=l+r>>1)>=k) ret=mid,r=mid-1; else l=mid+1;
		printf("%d\n",ret);
	}
	return 0;
}

Postscript

G题看了眼感觉挺复杂的直接弃疗了,感觉这场如果赛时打的话是个上大分的机会啊

标签:typedef,int,Codeforces,long,956,2024,include,RI,define
From: https://www.cnblogs.com/cjjsb/p/18292538

相关文章

  • 【全开源】2024最新版在线客服系统PHP源码(全新UI+终身使用+安装教程)
    PHP在线客服系统主要功能:1.用户信息用户提交:新用户可以通过表单留言输入相关信息,如用户名、密码、邮箱等,完成后获得唯一的用户ID和密码。2.客服管理客服信息管理:管理客服人员的基本信息,如姓名、工号、权限等。客服工作状态:实时显示客服人员的在线/离线状态,方便客户选择合......
  • 【2024最新】零基础如何学习挖漏洞?看这篇就够了(超详细)
    文章目录前言什么是漏洞挖掘学习漏洞挖掘的正确顺序漏洞挖掘需要具备的知识漏洞挖掘需要做什么有关漏洞挖掘的其他想法漏洞的复杂性团队工作写在最后==如何入门学习网络安全【黑客】==【----帮助网安学习,以下所有学习资料文末免费领取!----】大纲学习教程面试刷题资料......
  • 国开大学2024《社会保障基础(统设课)》
    1.养老保险通过强制性的分摊机制,为老年人提供足够收入以维持退休后的基本生活水平,防范老年风险,这是养老保险的()。答案:B.保险功能2.职工达到法定退休年龄,缴费未满15年,则()。答案:D.一次性领取个人账户储存额3.目前我国养老保险基金筹集的主要模......
  • codeforces 955 div 2 D
    题目链接D.Beautyofthemountains题目大意解题思路首先记录所有雪山和没有雪山两种山峰的高度差为\(tot\),然后对于每个可能的子矩,我们可以每次给所有山峰都加一或者减一,因此只要计算出矩阵内两种山峰的个数差的绝对值我们就能得到每次操作该子矩阵对tot的贡献\(z_{i}......
  • SMU Summer 2024 Contest Round 2
    Sierpinskicarpet1.这道题的核心其实在于,我们要观察到点的位置是在每一个小图形的正方形内,和一个大图型的中心正方形处的,那么通过观察可以发现,如果满足在这个正方形处,那么一定(3k-1+1)<=x,y<=(2*3k-1)2.这个k是什么意思呢?当我们n=3的时候k可以取1,2,3,也就是对应每一级的中间宫......
  • 2024年国内最经典好用的5款项目管理软件工具助你一路长虹
    目前市场上的项目管理软件众多,但是它们也都有一些共同的功能及特点。比如任务和进度管理、资源分配、财务监控、风险评估、协作增强以及报告和洞察力等。这些功能不仅提供了强大的工具来确保项目的高效执行和按时交付,而且还为团队成员和管理者提供了实时的数据和信息,帮助他们快速......
  • 【学术会议征稿】第八届电气、机械与计算机工程国际学术会议(ICEMCE 2024)
    第八届电气、机械与计算机工程国际学术会议(ICEMCE2024)20248th InternationalConferenceonElectrical,MechanicalandComputerEngineering第八届电气、机械与计算机工程国际学术会议(ICEMCE2024)将于2024年10月25日至27日在中国西安举办。本次会议由西京学院主办,自201......
  • 2024年全国青少年信息素养大赛图形化编程小高组复赛真题
    2024年全国青少年信息素养大赛图形化编程小高组复赛真题题目总数:6  总分数:100编程题第1题  问答题请对变身鱼进行编程,变身鱼的初始状态已经设置,不需要进行修改,1.当变身鱼大小大于300时,游戏胜利(自制积木块已经写好,可直接使用)。变身鱼碰到螃蟹,大小增加5,1秒后可......
  • 2024年北京市科学技术奖提名程序及注意事项
    2024年北京市科学技术奖的提名程序已然拉开帷幕,标志着又一轮科技荣耀的角逐正式开始。本年度提名不仅承载着对科研成就的高度认可,也体现了北京市推动科技进步、鼓励创新创造的坚定承诺。根据最新通知,提名工作已全面转入线上平台,确保提名流程的高效与透明。参与者需细致研读《关......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【前缀和/固定滑窗】2
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路贪心思想......