夏令营501-511NOIP训练17——蛇形矩阵
传送门:QAQQAQ
题意:话说小X在孩提时,都会做标准的蛇形矩阵了,发现很好玩。现在的小X很想对其进行改版,变为如下类型的一个无限大蛇形数阵:
令S(x)表示以1为左上角,x为右下角的矩形内所有数之和。例如S(12)就是具有深色背景的数之和。
给定n,对于“以1为左上角,n为右下角的矩形”内的每一个数i,计算所有S(i)之和。
思路:神仙数学题。。。
先看暴力:我们通过人工YY和简单推算可以得出一个公式:$ans=\sum_{i=1}^{n}\sum_{j=1}^{m}a_{i,j}*\left ( n-i+1 \right )*\left ( m-j+1 \right )$
那么我们可以在$O(n)$的复杂度内解决问题
现在开始优化环节:我们可以把一个给定矩形拆分成若干条链,使每一条链都是一个连续的数列(莫名想到树链剖分。。。)
具体拆分方法为:若是一个长方形,则先把多余的行或列拆出来,把它变成一个正方形。然后对于每一圈,我们先竖着拆$rnd$个,再横着拆$rnd-1$个,拆完为止。
现在我们的任务是求一个连续序列的和。每一个的统计总和为$a_{i,j}*\left ( n-i+1 \right )*\left ( m-j+1 \right )$,而且这个序列一定在同一行或同一列,所以我们可以把$\left ( n-i+1 \right )$或$\left ( m-j+1 \right )$中的一项提取出来,这样剩下的就是两项相乘求和了。而我们发现这两项分别在两个公差为$1$或$-1$的等差数列中。
现在开始数学环节——暴力推公式
令$f(s1,s2,d1,d2,n)$为首项为$s1$,公差为$d1$的等差数列和首项为$s2$,公差为$d2$的等差数列每一项分别相乘,前$n$项乘积的和
即:$f(s1,s2,d1,d2,n)$=$\sum_{i=1}^{n}\left [ s1+\left ( i-1 \right )*d1 \right ]*\left [ s2+\left ( i-1 \right )*d2 \right ]$
=$\sum_{i=1}^{n}(s1*s2)+\sum_{i=1}^{n}(s1*d2*(i-1))+\sum_{i=1}^{n}( d1*s2*(i-1))+\sum_{i=1}^{n}( d1*d2*(i-1)^{2} )$
=$n*s1*s2+s1*d2*\sum_{i=1}^{n-1}i+s2*d1*\sum_{i=1}^{n-1}i+d1*d2*\sum_{i=1}^{n-1}i^{2}$
=$n*s1*s2+s1*d2*\frac{(n-1)*n}{2}+d1*s2*\frac{(n-1)*n}{2}+d1*d2*\frac{(n-1)*n*(2*n-1)}{6}$
那么我们现在就可以用$O(1)$的时间算出每一条链,而一共拆成$\sqrt{n}$条链,所以总复杂度$\sqrt{n}$
代码:(注意代码实现时$x,y$很容易弄混)
#include<bits/stdc++.h>
#define pii pair<ll,ll>
#define mk make_pair
using namespace std;
typedef long long ll;
const ll MOD=(ll)1e9+;
const ll inv2=;
const ll inv6=; pii find(ll x)
{
ll rnd=(ll)sqrt(x);
if(rnd*rnd!=x) rnd++;
ll End=rnd*rnd;
ll dif=End-x;
ll posx,posy;
if(rnd%==)
{
posx=rnd; posy=;
if(dif<=rnd-) posy+=dif;
else
{
posy=rnd; dif-=(rnd-);
posx-=dif;
}
}
else
{
posx=,posy=rnd;
if(dif<=rnd-) posx+=dif;
else
{
posx=rnd; dif-=(rnd-);
posy-=dif;
}
}
return mk(posx,posy);
} void fn(ll &x)
{
x=(x%MOD+MOD)%MOD;
} ll f(ll s1,ll s2,ll d1,ll d2,ll n)
{
if(n==) return ;
ll ret=n*s1%MOD*s2%MOD; fn(ret);
ret=(ret+n*(n-)%MOD*inv2%MOD*(s1*d2%MOD+s2*d1%MOD))%MOD; fn(ret);
ret=(ret+n*(n-)%MOD*(*n-)%MOD*inv6%MOD*d1%MOD*d2%MOD); fn(ret);
return ret;
} int main()
{
ll x,ans=;
scanf("%lld",&x);
pii pos=find(x);
ll n=pos.first,m=pos.second;
ll nowx=n,nowy=m;
while(nowx>m)
{
if(nowx%==)
{
ll k=n-nowx+;
ll s1=(nowx-)*(nowx-)+; ll d1=;
ll s2=m; ll d2=-;
ans=(ans+k*f(s1,s2,d1,d2,m))%MOD;
}
else
{
ll k=n-nowx+;
ll s1=nowx*nowx; ll d1=-;
ll s2=m; ll d2=-;
ans=(ans+k*f(s1,s2,d1,d2,m))%MOD;
}
nowx--;
}
while (nowy>n)
{
if(nowy%==)
{
ll k=m-nowy+;
ll s1=nowy*nowy; ll d1=-;
ll s2=n; ll d2=-;
ans=(ans+k*f(s1,s2,d1,d2,n))%MOD;
}
else
{
ll k=m-nowy+;
ll s1=(nowy-)*(nowy-)+; ll d1=;
ll s2=n; ll d2=-;
ans=(ans+k*f(s1,s2,d1,d2,n))%MOD;
}
nowy--;
}
while(nowx>&&nowy>)
{
if(nowx%==)
{
ll k=m-nowy+;
ll s1=nowy*nowy; ll d1=-;
ll s2=n; ll d2=-;
ans=(ans+k*f(s1,s2,d1,d2,nowx))%MOD;
k=n-nowx+;
s1=(nowx-)*(nowx-)+; d1=;
s2=m; d2=-;
ans=(ans+k*f(s1,s2,d1,d2,nowy-))%MOD;
}
else
{
ll k=m-nowy+;
ll s1=(nowy-)*(nowy-)+; ll d1=;
ll s2=n; ll d2=-;
ans=(ans+k*f(s1,s2,d1,d2,nowx))%MOD;
k=n-nowx+;
s1=nowx*nowx; d1=-;
s2=m; d2=-;
ans=(ans+k*f(s1,s2,d1,d2,nowy-))%MOD;
}
nowx--; nowy--;
}
cout<<ans<<endl;
return ;
}
夏令营501-511NOIP训练17——蛇形矩阵的更多相关文章
- XJOI 夏令营501-511NOIP训练17 蛇形数阵
话说小X在孩提时,都会做标准的蛇形矩阵了,发现很好玩.现在的小X很想对其进行改版,变为如下类型的一个无限大蛇形数阵:令S(x)表示以1为左上角,x为右下角的矩形内所有数之和.例如S(12)就是具有深色 ...
- EOJ3536 求蛇形矩阵每一行的和---找规律
题目链接: https://acm.ecnu.edu.cn/problem/3536/ 题目大意: 求蛇形矩阵的每一行的和,数据范围n<=200000. 思路: 由于n数据较大,所以感觉应该是需 ...
- EOJ 3.30 B. 蛇形矩阵【找规律/待补】
[链接]:https://acm.ecnu.edu.cn/contest/59/problem/B/ B. 蛇形矩阵 Time limit per test: 2.0 seconds Memory l ...
- js实现蛇形矩阵
参加腾讯前端实习生笔试,真的是被虐了千百遍,除了一条js程序题,其他半点前端都没有,都是考算法,计算机原理,数据结构.下面贴上腾讯笔试最后三大条中的一条,实现一个蛇形矩阵的输出.蛇形矩阵的什么样这里我 ...
- 【面试】输出"蛇形"矩阵
一.题目描述 腾讯实习在线笔试的一道题目. 根据输入的数字(< 1000),输出这样的"蛇形"矩阵,如下.输入n,输出(n * n)阶矩阵,满足由外到内依次增大. 如: 输入 ...
- c++实现蛇形矩阵总结
蛇形矩阵,百度了一下,是这么一个东西: 像一条蛇一样依次递增. 我想,竟然做了螺旋矩阵,那做一下这个吧.在之前的螺旋矩阵的main函数基础上,写个函数接口就行了,这一次做的很快,但是这个矩阵感觉比螺旋 ...
- wikioi 1160 蛇形矩阵
/*======================================================================== 1160 蛇形矩阵 题目描述 Descriptio ...
- Java编码 蛇形矩阵的构建与遍历输出
一.蛇形矩阵的构建,并按行输出 例: 输入:n, 生成n*n的蛇形矩阵 1 2 3 8 9 4 7 6 5 输出:1 2 3 8 9 4 7 6 5 java编码 public static void ...
- c++打印蛇形矩阵
一个m*n的矩阵里按照下图形式填充,最后形成的矩阵即为蛇形矩阵,下图是m=4, n =5时的蛇形矩阵: 方法一:逐层循环 #include <iostream> using namespa ...
随机推荐
- 单个机器部署redis集群模式(一键部署脚本)
一.检查机器是否安装gcc.unzip.wget 二.部署模式 #模式1: 将所有主从节点以及sentinel节点部署在同一台机器上 #模式2: 将一个数据节点和一个sentinel节点部署在一台机器 ...
- HTML+CSS项目——模拟京东网页
项目准备 项目名称:京东商城 项目描述:京东首页公共部分的头部和尾部制作,京东首页中间部分. 设计目标 保证浏览器 ie7及以上, 火狐, 360, safari,chrome等.谁让我再测ie6,就 ...
- NOIp2018集训test-9-8(pm) (联考一day2)
把T1题读错了,想了一个多小时发现不可做.然后打了t2,常数不优秀.然后去打t3,lct,结果打挂爆0了. 然后今天就爆炸了. 如果这是noip我今年就可以直接回去学常规了.学常规多好,多开心. 今天 ...
- 暑假集训test-8-28
大概是从我一年以来做过的最傻逼的一套题了.. 一个半小时打完三个程序三个暴力拍完以为自己AK了,开心地耍了两个小时. 结果T3要写高精,LL炸了后4个点,中间还有个点是啥都不选的,我没用0去更新又炸了 ...
- NX二次开发-UFUN多按钮模态对话框UF_UI_message_dialog
NX11+VS2013 #include <uf.h> #include <uf_ui.h> UF_initialize(); //多按钮模态对话框 ; char title_ ...
- sqlserver 获取实例上用户数据库的数据字典
原理很简单:将获取数据字典信息(通过动态视图获取)存入到目标表(数据字典表)中即可. 本人自用实例 1)创建相关的字典表 use YWMonitor GO SET ANSI_NULLS ON GO S ...
- Java-Class-I:java.util.Map
ylbtech-Java-Class-I:java.util.Map 1.返回顶部 1.1. import java.util.HashMap; import java.util.Map; 1.2. ...
- Spring源码由浅入深系列六 CreateBean过程
- LED 发光二极管压降
常用发光二极管的压降 1. 直插超亮发光二极管压降 主要有三种颜色,然而三种发光二极管的压降都不相同,具体压降参考值如下: 红色发光二极管的压降为2.0--2.2V 黄色发光二极管的压降为1.8—2 ...
- Java 中的 SPI 机制是什么鬼?高级 Java 必须掌握!
作者:sigangjun blog.csdn.net/sigangjun/article/details/79071850 SPI的全名为:Service Provider Interface,大多数 ...