Codeforces Round #841 (Div. 2)

2023-05-16

B Kill Demodogs

分析

显然要选择(i,i)(i,i+1)两斜线的元素相加

所以答案可以表示为:\sum\limits_{i=1}^n i^2 + \sum\limits_{i=1}^{n-1} (i+1)i

即:2\sum\limits_{i=1}^{n-1} i^2+n^2+\sum\limits_{i=1}^{n-1}i

根据公式\sum\limits_{k=1}^n k^2=1^2+2^2+3^2+...+n^2=\frac{n^3}{3}+\frac{n^2}{2}+\frac{n}{6}=\frac{n(n+1)(2n+1)}{6}

得答案为\frac{(n-1)n(2n-1)}{3}+n^2+\frac{n(n-1)}{2}

但答案不能直接得这个。因为n的范围为1e9,而ull的范围为1e20,答案的第一项中n^3项最大为1e27,会导致溢出,因此要对答案式子进行变换。

能直接将式子中的每个部分直接逐个放到答案ans上吗?不行

因为(n-1)n(2n-1)能被3整除,但分开后不一定能被3整除,进而导致在相乘->取余->相乘的过程中产生误差。

所以要将原式分解为整数相乘相加的形式。

经过一系列因式分解可得式子\frac{n(2n^2+1)}{3}+\frac{n(n-1)}{2}

因为原式第一项的分子(n-1)n(2n-1)能被3整除,而变换后的式子第一项分子相当于减了一个3n^2(3的倍数),还能被3整除。

所以,如果n不能被3整除,则n(2n^2+1)的因子3必然在2n^2+1中存在;否则因子3一定在n中存在。

至此,可以使用long long进行程序实现。

代码实现

#include<bits/stdc++.h>
#define ll long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
void solve(){
	ll n;
	ll ans=0;
	cin>>n;

	if(n%3==0){
		ans=2*n*n+1;
		ans=ans%1000000007;
		ans*=n/3;
		ans=ans%1000000007;
	}
	else{
		ans=(2*n*n+1)/3;
		ans=ans%1000000007;
		ans*=n;
		ans=ans%1000000007;
	}
	ans+=(n-1)*n/2;
	ans=ans%1000000007;

	ans=ans*2022;
	ans=ans%1000000007;
	cout<<ans<<"\n";
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
} 

C. Even Subarrays

分析

容易看出,不符合要求的区间段异或结果为k^2(k=0,1,2...)。长度为n的子区间段总数为\frac{n(n+1)}{2},所以总数减去不符合要求的区间段个数就是答案ans。

小知识:异或前缀和。若sum5=a_{1}\oplus a_{2}\oplus a_{3}\oplus a_{4}\oplus a_{5}sum2=a_{1}\oplus a_{2},则a_{3}\oplus a_{4}\oplus a_{5}=sum5\oplus sum2

在算异或前缀和的过程中处理答案。步骤:①算出当前位置的异或前缀和x;②暴力查找x分别与所有平方数的异或结果是否出现过(num=cut[x^平方数]),出现次数为numi,ans-=numi;③更新cnt数组,cnt[x]++;

代码实现

#include<bits/stdc++.h>
#define ll long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
int cnt[1000006];
int sum[1000006];
vector<int>sqr;
void solve(){
	ll n, ans=0;
	memset(cnt,0,sizeof(cnt));
	cnt[0]++;
	cin>>n;
	ans=n*(n+1)/2;
	rep(i,1,n){
		cin>>sum[i];
		sum[i] ^= sum[i-1];
		for(auto x : sqr){
			ans -= cnt[sum[i]^x];
		}
		cnt[sum[i]]++;
	}
	cout<<ans<<"\n";
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for(int i=0;i*i<=400005;i++){
		sqr.push_back(i*i);
	}
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
} 

D. Valiant's New Map

分析

关键字:二分答案,二维前缀和处理降低check复杂度。

要敢于大胆地断定可以二分答案。(其实看到n*m<=1e6时就该有所反应。1e6乘上log级的二分很难超过1e9的极限)

然后是确定边界,以及怎么check。

边界:l=1,r=mid(n,m)。可以看出r最大为1e3,很小。

check:对于每个mid,先将原数组a[i][j]中令符合条件的元素等于1,不符合条件的元素等于0,然后令开一个数组存二维前缀和,将判断范围由“单个方块”变为“一个区块”。好处是,原来需要对一个区块的每个元素都做一次判断,单次判断的复杂度为O(mid^2),而现在有了橙色的预处理步骤,对一个区块可以直接通过一步简单运算(二维前缀和的运算)判断该区块是否符合要求,复杂度为O(1)。预处理结束后暴力判断整个n*m区域的每个mid*mid的区块。复杂度O(n*m*log(min(n,m))),最大1e7。

PS:

①代码中的注释为一种 二分不容易错 的写法,值得注意。

②二维vector的定义方法,值得记忆。

代码实现

#include<bits/stdc++.h>
#define ll long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define fastio() ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define V vector<int>
#define VV vector<V>
#define pii pair<int,int>
#define Vpii vector<pii>
using namespace std;
int n,m;
bool check(int mid, VV a){
	VV sum(n+1, V(m+1));
	rep(i,1,n){
		rep(j,1,m){
			if(a[i][j]>=mid) a[i][j] = 1;
			else a[i][j] = 0;
			sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + a[i][j];
		}
	}
	rep(i,1,n-mid+1){
		rep(j,1,m-mid+1){
			if(sum[i+mid-1][j+mid-1] - sum[i+mid-1][j-1] - sum[i-1][j+mid-1] + sum[i-1][j-1] == mid*mid)
			return true;
		}
	}
	return false;
}
void solve(){
	int l=1,r,mid;
	cin>>n>>m;
	r=min(n,m);
	VV a(n+1,V(m+1));
	rep(i,1,n){
		rep(j,1,m){
			cin>>a[i][j];
		}
	}
	while(l<r){
		mid=(l+r+1)>>1;
		if(check(mid, a)) l=mid;
		else r=mid-1;
	}
	/*
	int ans;
	while(l<=r){
		mid=(l+r)>>1;
		if(check(mid, a)){
			ans=mid;
			l=mid+1;
		}
		else r=mid-1;
	}
	cout<<ans<<"\n";
	*/
	cout<<r<<"\n";
}
int main(){
	fastio();
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Codeforces Round #841 (Div. 2) 的相关文章

随机推荐

  • [区间DP/状压DP]Exercise Week12 A~E

    目录 A 水 找数题意样例样例输入 xff1a 样例输出 思路总结代码 B BFS 逃离题意样例样例输入 xff1a 样例输出 xff1a 思路总结代码 C DP 扫楼题意样例样例输入 xff1a 样例输出 思路总结代码 D 区间DP 最长
  • 新的开始( [USACO08OCT]打井Watering Hole)

    新的开始 newstart pas c cpp 题目描述 话说小 FF 在经历了上次 寻找古代王族遗产 的探险后 xff0c 成为了世界上最伟大的探险 家并拥有了一大笔财富 当然他不能坐吃山空 xff0c 必须创造财富 xff01 xff0
  • UOS配置本地APT源和外部软件包

    root 64 skill PC mount dev sr0 mnt mount mnt WARNING device write protected mounted read only root 64 skill PC vi etc ap
  • [二分答案] 洛谷P1873 砍树

    目录 题意样例样例输入 xff1a 样例输出 思路总结代码 题意 伐木工人米尔科需要砍倒M米长的木材 这是一个对米尔科来说很容易的工作 xff0c 因为他有一个漂亮的新伐木机 xff0c 可以像野火一样砍倒森林 不过 xff0c 米尔科只被
  • [区间DP]洛谷P1063 能量项链

    目录 题意样例样例输入 xff1a 样例输出 思路总结代码 题意 样例 样例输入 xff1a 4 2 3 5 10 样例输出 710 思路 1 经典区间DP题 算是合并石子的变种 只不过由一个点变成了一个区间 不过我们也可以用结构体存储 当
  • Linux命令行初接触-1 操作文件和目录

    操作文件 amp 目录 1 通配符含义常用通配符常用字符类类型匹配范例 2 mkdir 创建目录3 cp 复制文件和目录工作方式常用选项 4 mv 移动和重命名文件工作方式常用选项 5 rm 删除文件和目录工作方式常用选项注意事项 6 ln
  • 机器学习入入入入门(1)机器学习基本概念、引出深度学习

    机器学习入入入入门 xff08 1 xff09 0 前言1 基本步骤2 基本概念2 1 Hyperparameters2 2 local minima 3 linear model3 1 基础概念 4 piecewise linear cu
  • 深度学习蒟蒻入门——从0安装pytorch(CPU版)

    从0安装pytorch 1 检查自己的电脑有没有GPU2 安装CPU版的pytorch3 测试pytorch 1 检查自己的电脑有没有GPU 首先打开任务管理器 xff0c 选择性能栏 然后滑到最下 xff0c 看是否有GPU一项 xff0
  • 系统学习iOS动画 —— Stroke和路径动画

    这是要完成的动画 xff1a 先添加需要的代码 xff0c 这里需要将storyboard的ViewController换成TableViewController xff0c 将Under Top Bars 和 Under Bottom B
  • 不知道这些网站还做什么程序员呀!

    今天我就来总结一些程序员必备的网站 xff0c 囊括开源项目 解决bug 技术分享 一线资源和自我提升的网站 xff0c 希望能对广大程序猿有所帮助 xff0c 赶紧给我收藏起来 xff0c 下次刷不到了可别说我没提醒你 我们首先来看一下国
  • (音视频开发)WebRTC进阶流媒体服务器开发-多人互动架构

    一 xff1a 多人互动架构方案 xff08 一 xff09 WebRTC回顾 xff0c 两层含义 xff1a 1 WebRTC是google开源的流媒体客户端 xff0c 可以进行实时通讯 xff0c 主要应用于浏览器之间进行实时通讯
  • 10种linux下磁盘快照方式恢复系统

    导读大家都知道windows系统有一个磁盘快照的功能 xff0c 在windows2003中系统恢复开始依赖于一个叫做硬盘快照服务 Volume Snapshot Service 的服务 xff0c 他能够自动创建系统快照 包括正在使用的文
  • ubuntu安装go开发环境

    一 为ubuntu20 04更新源 给root用户设置密码 xff1a 命令 xff1a sudo passwd root 备份原来的源 xff0c 命令 xff1a sudo cp etc apt sources list etc apt
  • 如何修复Ubuntu中包缓存文件被毁问题

    导读今天 xff0c 我尝试更新我的 Ubuntu 18 04 LTS 的仓库列表 xff0c 但收到了一条错误消息 xff1a E The package cache file is corrupted it has the wrong
  • 1002 A+B for Polynomials (25分) 详解+易错点

    注意点 xff1a 系数为0 xff0c 则不输出 xff0c 例 xff1a 其中 1和1相加为0 xff0c 则在输出时避免这一项 xff0c 而且要注意结果的K值 xff0c 不要包括这一项 xff0c 思路 xff0c 利用结构体存
  • Linux远程桌面的选择

    Linux的远程桌面主要分两个部分 xff1a Linux客户机连Linux服务器和Windows客户机连Linux服务器 xff0c 还有现在用平板电脑连远程桌面 Linux客户机连Windows服务器比较简单没啥可说的 xff0c rd
  • Kali Linux mdk3WiFi洪水攻击 攻击路由器 生成虚假WiFi WiFi身份验证攻击可使连接WiFi的手机掉线重连抓包

    将无线网卡转换为监听模式 airmon ng start wlan0 查找附近无线网络 airodump ng wlan0mon Authentication DoS xff1a xff08 洪水攻击 xff0c 又叫做身份验证攻击 xff
  • 大一java程序设计的某次作业题解

    题目描述 xff1a 设计程序实现输入日期及机票张数 xff0c 计算出应付金额 假设北京至上海的机票全价为 1200 元 张 xff0c 以 2017 年为例进行程序编写 xff0c 所有的法定假日 xff0c 机票无折扣 xff1b 除
  • D. Make It Round(1759D)

    要求n k后缀0数量最多 xff08 k lt 61 m xff09 xff0c 且n k尽可能大 比赛时思路 xff08 错误 xff09 xff1a 10是由2和5组成 xff0c 故先统计n的因子包含2的个数num2 包含5的个数nu
  • Codeforces Round #841 (Div. 2)

    B Kill Demodogs 分析 显然要选择和两斜线的元素相加 所以答案可以表示为 xff1a 即 xff1a 根据公式 得答案为 但答案不能直接得这个 因为n的范围为1e9 xff0c 而ull的范围为1e20 xff0c 答案的第一