牛客编程巅峰赛S2第4场

牛牛摆玩偶

题目描述

牛牛有\(n(2 \leq n \leq 10^5)(2≤n≤105)\)个玩偶,牛牛打算把这n个玩偶摆在桌子上,桌子的形状的长条形的,可以看做一维数轴。 桌子上有 \(M\) 个互不相交的区间\((1≤M≤10^5)\),这些区间上面可以放玩偶。一个位置只能放一个玩偶,玩偶之间的距离越大越美观,牛牛想最大化 D 的值,其中 D 为最近的两个玩偶之间的距离。请帮牛牛求出 D 的最大可能值。

示例1

输入

5,3,[[0,2],[4,7],[9,9]]

返回值

2

备注:

区间长度\(\leq 2^{31} -1\)

思路:

最大最小值,最小最大值,一看就是二分。比赛中就是过不了(\(90\%\)的数据), 肯定思路没错,以为是数据错了(*^▽^*)。

思路数据没错,应该首先想到是不是时间复杂度太高,应该是judge函数的时间复杂度高了。下次一定注意。

代码

/**
* struct Interval {
* int start;
* int end;
* Interval(int s, int e) : start(start), end(e) {}
* };
*/ #define ll long long
const int maxn = 2e5+10; class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param n int整型 玩偶数
* @param m int整型 区间数
* @param intervals Interval类vector 表示区间
* @return int整型
*/
bool judge(ll x, vector<pair<ll, ll> > inv, int n){
//n--;
ll pos = -2e10;
/* 复杂度太高?
for(auto ine : inv){
if(pos + x <= ine.first){
pos = ine.first;
n--;
}
if(n <= 0) return true;
while(pos + x <= ine.second){
pos += x;
n--;
if(n <= 0) return true;
}
}
*/
for(auto in : inv){
ll l = max(pos+x, in.first);
if(l > in.second) continue;
ll t = (in.second - l) / x;
n -= (t+1);
if(n <= 0) return true;
pos = l + t*x;
}
return n <= 0;
}
int doll(int n, int m, vector<Interval>& intervals) {
// write code here
vector<pair<ll, ll> > inv;
for(auto ine : intervals) {
inv.push_back({1ll * ine.start, 1ll * ine.end});
}
sort(inv.begin(), inv.end(), [](const pair<ll, ll> &a, const pair<ll, ll> &b)->bool{
return a.first < b.first;
}); ll l = 0, r = inv.back().second - inv[0].first;
ll ans = -1;
while(l <= r){
ll mid = l + (r - l) / 2;
if(judge(mid, inv, n)){
ans = mid;
l = mid + 1;
}else r = mid - 1;
}
return ans;
}
};

交叉乘

题目描述

上小学二年级的牛牛已经精通整数的加法和乘法。现在你要考考他。你先给出一个整数数组\(a_1,a_2,...,a_n\),然后每次你会给一对整数\(l,r(l≤r)\),牛牛需要算出\(\sum_{i=l}^{r} \sum_{j=i+1}^{r} a_i*a_j\)​的值。但是牛牛算完之后你不能不确定他算得对不对,为了验证他的答案,你决定自己算一遍。

为了不输出过大的答案,假设答案为\(ans\),请输出\(ans \% 1,000,000,007\)。

提示:

在\(\%1,000,000,007\)的意义下\(/2\)相当于\(*500,000,004\)

示例1

输入

[1,2,5,3,4],[1,4,2,5,2,2]

返回值

[41,71,0]

说明

第一个询问,l=1,r=4,ans=1*2+1*5+1*3+2*5+2*3+5*3=41;
第二个询问,l=2,r=5,ans=2*5+2*3+2*4+5*3+5*4+3*4=71;
第三个询问,l=2,r=2,ans=0。

备注:

参数\(a\)为\(vector<int>\),依次为\(a_1,a_2,...,a_n\);

参数\(query\)为\(vector<int>\),依次为\(l_1,r_1,l_2,r_2,...,l_q,r_q\);

\(n\)为数组\(a\)长度,\(q\)为询问次数。

\(30\%\) 数据满足 \(1<=n,q<=1000\)

\(100\%\) 数据满足 \(1<=n,q<=100000,1<=a_i<=100000,1<=l_i<=r_i<=n\)

思路

没想出来,思路是听直播学的。

九九乘法表,划掉对角线,前缀和优化。

就是主对角线下面的等式之和,矩阵里对角线上面的元素和下面的元素和相同,故可以总体相加,如下图:

求和公式:\(\sum_{i=l}^{r} \sum_{j=i+1}^{r} a_{i} * a_{j}=\frac{\left(\sum_{i=l}^{r} a_{i}\right)^{2}-\sum_{i=l}^{r} a_{i}^{2}}{2}\)

另外:题目中数较大。需要开long long。用到了逆元的知识。

代码

#define ll long long
const int mod = 1e9+7;
const int maxn = 2e5+10;
ll sum[maxn], mul[maxn];
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 多次求交叉乘
* @param a int整型vector a1,a2,...,an
* @param query int整型vector l1,r1,l2,r2,...,lq,rq
* @return int整型vector
*/
vector<int> getSum(vector<int>& a, vector<int>& query) {
// write code here
sum[0] = mul[0] = 0;
for(int i = 1; i <= a.size(); i++){
sum[i] = (sum[i-1] + a[i-1]) % mod;
mul[i] = (mul[i-1] + 1ll * a[i-1]*a[i-1] % mod) % mod;
}
vector<int> ans;
for(int i = 0; i < query.size(); i+=2){
int l = query[i], r = query[i+1];
ll t = (sum[r] - sum[l-1]) % mod;
ll res = (t * t % mod - (mul[r]-mul[l-1])% mod + mod)% mod ;
res = (res * 500000004 % mod + mod) % mod;
ans.push_back(res);
}
return ans;
}
};

牛客编程巅峰赛S2第4场的更多相关文章

  1. 牛客编程巅峰赛S2第10场 - 钻石&王者 C.牛牛的路径和 (位运算,dfs)

    题意:给你节点数为\(n\)的树,每个节点都有自己的权值,求所有路径的上的点的权值按位与的和. 题解:题目给的数据很大,我们不能直接去找.因此我们可以枚举二进制\([1,20]\)的每一位,然后再枚举 ...

  2. 牛客编程巅峰赛S2第7场 - 钻石&王者 A.牛牛的独特子序列 (字符串,二分)

    题意:给你一个字符串,找出一个类似为\(aaabbbccc\)这样的由连续的\(abc\)构成的子序列,其中\(|a|=|b|=|c|\),问字符串中能构造出的子序列的最大长度. 题解:这题刚开始一直 ...

  3. 牛客编程巅峰赛S2第3场 Tree VI (树,dfs)

    题意:给你一个\(n\)个点的完全\(k\)叉树的先序遍历序列\(a\),还原这颗树并且求所有两个端点的异或和. 题解:用dfs在还原树的时候,把子节点和父亲节点的异或贡献给答案,对于每个节点,我们找 ...

  4. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)

    题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...

  5. 牛客编程巅峰赛S1第11场 - 黄金&钻石 C.牛牛找子集 (二分)

    题意:有一\(n\)个数,从中找数构成相同的子集,要求子集元素个数为\(k\),求构成子集个数最多的情况,输出子集(字典序最小). 题解:我们可以对子集的个数二分答案,首先用桶记录每个元素的个数,然后 ...

  6. 牛客编程巅峰赛S1第11场 - 黄金&钻石 B.新集合 (DFS)

    题意:有\([1,n]\)这\(n\)个数,构造集合,集合中不能包含\(u\)和\(v\),问最多能构造多少个集合. 题解:被这题卡了一整场.....以为是推公式,结果答案是暴搜? ​ 首先我们先用一 ...

  7. 牛客编程巅峰赛S1第11场 - 黄金&钻石 A.牛牛的01游戏 (模拟栈)

    题意:有一个\(01\)串,两个相邻的\(0\)可以变成一个\(1\),两个相邻的\(1\)可以直接消除,问操作后的字符串. 题解:数组模拟栈直接撸,上代码吧. 代码: class Solution ...

  8. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 B.牛牛摆放花 (贪心)

    题意;将一组数重新排序,使得相邻两个数之间的最大差值最小. 题解:贪心,现将所有数sort一下,然后正向遍历,将数分配到新数组的两端,然后再遍历一次维护一个最大值即可. 代码: class Solut ...

  9. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 A.牛牛爱奇数 (模拟)

    题意:有一组数,每次将所有相等的偶数/2,求最少操作多少次使得所有数变成奇数. 题解:用桶标记,将所有不同的偶数取出来,然后写个while模拟统计一下次数就行. 代码: class Solution ...

随机推荐

  1. Go module 本地导包方式

    tip本文只讲关于Go module 本地导包方式,其他请自行查阅 Go module 导包方式,go mod init project-name,会得到一个go.mod文件,此文件是管理依赖的,通常 ...

  2. python装饰器是什么?

    装饰器是python中的高阶语法,装饰器是通过类或者函数来实现的,通常使用@符号来表示一个装饰器,作用是用来扩展某个函数或者类的功能

  3. NB-IOT覆盖能力有多强 是怎么实现的

    NB-IoT技术中出现以来就以其强大的覆盖能力和通信距离长而受到广大使用者的欢迎,那么NB-IoT覆盖能力究竟是有多大,其覆盖能力应该怎么来衡量? 强大的覆盖能力是NB-IoT技术的最大特点之一,不仅 ...

  4. python制作电脑可执行exe文件

    python获取IP.主机名.mac地址 关注公众号"轻松学编程"了解更多. 制作get_IP.py文件: import socket import uuid # 获取主机名 ho ...

  5. 浅谈querySelector和getElementById之间的区别

    前言: 最近学到前端一些知识,看到很多视频上许多老师都用的是querySelector而部分老师用的是getElementById,我就很疑惑,这两有啥区别,都是选择器,于是百度了一下明白了,quer ...

  6. Pycharm激活码(2020最新永久激活码)

    如果下边的Pycharm激活码过期失效了的话,大家可以关注我的微信公众号:Python联盟,然后回复"激活码"即可获取最新Pycharm永久激活码! 56NPDDVEIV-eyJs ...

  7. layui下拉框实现级联

    <!DOCTYPE html><html><head> <meta charset="utf-8" /> <link href ...

  8. 天啦噜!仅仅5张图,彻底搞懂Python中的深浅拷贝

    Python中的深浅拷贝 在讲深浅拷贝之前,我们先重温一下 is 和==的区别. 在判断对象是否相等比较的时候我们可以用is 和 == is:比较两个对象的引用是否相同,即 它们的id 是否一样 == ...

  9. impala-shell -o a.txt 查询中有中文时报错问题的处理

    当使用impala-shell -o a.txt进入impala-shell之后,查询报错: 报错情况: Query: select * from dim_sales_dept Unknown Exc ...

  10. tomcat 404报错 问题可能之一

    一个tomcat下多个应用:我的应用xxx启动不起来,页面报错404: May 29, 2015 5:58:37 PM org.apache.catalina.core.StandardContext ...