题目

思路

暴力很好打,我们显然可以先把关于 \(k\) 的式子拆开

先二项式展开,然后把外面的 \(m\) 乘进去,把 \(p\) 的分母 \(m\) 消去

\(K = (\sum_{i=1}^m (x_i - p)^2) \times m = m \times \sum_{i=1}^m x_i^2 - (\sum_{i=1}^m x_i)^2\)

发现它只剩下整数的乘和减运算

其实可以看出我们需要维护的东西:区间小于等于 \(z\) 的数的个数,这些数的和,这些数的平方的和

那么我们怎么维护区间小于等于 \(z\) 的数的信息呢?

对于这种二维偏序问题,经典的做法是在线的主席树

然而空间卡得不行不行的

所以我们考虑离线做法

依照题目意思,唯有 \(w \leq z\) 的数会对当前答案产生贡献

我们离线,先按照 \(w,z\) 从小到大排序

那么我们按这个顺序做下去,每遇到一个点就将其以它在原序列中的编号插入到某种数据结构中

遇到一个询问时,我们已经保证了 \(w \leq z\) 的数在这个数据结构中,只要查询区间 \([l..r]\) 的信息就好

因为空间的恶心,推荐使用树状数组

\(Code\)

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL; const int N = 4e5 + 5;
const LL INF = -1e18 - 1e15;
LL m , ps1 , ps2 , ans[N];
int n , q , h[N] , tot; struct question{
int to , nxt;
}c[N]; struct ask{
int x , y , z , id;
}a[N]; struct node{
int w , id;
LL pos;
}b[N]; struct segment{
int cnt;
LL pos1 , pos2;
}seg[N]; inline bool cmp1(node x , node y){return x.w < y.w;}
inline bool cmp2(ask x , ask y){return x.z < y.z;}
inline void addask(int id1 , int id2){c[++tot].to = id2 , c[tot].nxt = h[id1] , h[id1] = tot;}
inline int lowbit(int x){return x & (-x);} inline void update(int x , int ct , LL p1 , LL p2)
{
for(; x <= n; x += lowbit(x))
seg[x].cnt += ct , seg[x].pos1 += p1 , seg[x].pos2 += p2;
} inline void query(int x , int fl)
{
for(; x; x -= lowbit(x))
m += (LL)seg[x].cnt * fl , ps1 += seg[x].pos1 * fl , ps2 += seg[x].pos2 * fl;
} int main()
{
freopen("sequence.in" , "r" , stdin);
freopen("sequence.out" , "w" , stdout);
scanf("%d%d" , &n , &q);
for(register int i = 1; i <= n; i++) scanf("%d%lld" , &b[i].w , &b[i].pos) , b[i].id = i;
for(register int i = 1; i <= q; i++) scanf("%d%d%d" , &a[i].x , &a[i].y , &a[i].z) , a[i].id = i;
sort(b + 1 , b + n + 1 , cmp1) , sort(a + 1 , a + q + 1 , cmp2); int l , r , mid , res;
for(register int i = 1; i <= q; i++)
{
l = 1 , r = n , mid , res = 0;
while (l <= r)
{
mid = (l + r) >> 1;
if (b[mid].w <= a[i].z) res = mid , l = mid + 1;
else r = mid - 1;
}
if (res == 0) ans[a[i].id] = INF;
else addask(res , i);
}
for(register int i = 1; i <= n; i++)
{
update(b[i].id , 1 , b[i].pos , b[i].pos * b[i].pos);
for(register int j = h[i]; j; j = c[j].nxt)
{
int id = c[j].to;
ps1 = ps2 = 0 , m = 0;
query(a[id].y , 1) , query(a[id].x - 1 , -1);
if (m == 0)
{
ans[a[id].id] = INF;
continue;
}
ans[a[id].id] = m * ps2 - ps1 * ps1;
}
}
for(register int i = 1; i <= q; i++)
{
if (ans[i] == INF) printf("empty\n");
else printf("%lld\n" , ans[i]);
}
}

其实这题有个很暴力的方法

分块大法好!!!

我们维护一个分块数组

它包括每个点的 \(w,pos\)

然后同一块内的数按 \(w\) 从小到大排序

维护前缀和包括一次方和二次方的

查询只需要二分找块中的位置

前缀和更新即可

\(Code\)

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL; const int N = 4e5 + 5;
LL m , pos[N] , ps1 , ps2;
int n , q , w[N] , st[N] , ed[N] , num , belong[N]; struct node{
int w;
LL pos , pos1 , pos2;
}t[N]; inline bool cmp(node x , node y){return x.w < y.w;} inline void parepre()
{
num = (int)sqrt(n);
for(register int i = 1; i <= num; i++) st[i] = n / num * (i - 1) + 1 , ed[i] = n / num * i;
ed[num] = n;
for(register int i = 1; i <= num; i++)
{
for(register int j = st[i]; j <= ed[i]; j++) belong[j] = i , t[j] = (node){w[j] , pos[j] , 0 , 0};
sort(t + st[i] , t + ed[i] + 1 , cmp);
for(register int j = st[i]; j <= ed[i]; j++)
{
(j == st[i] ? (t[j].pos1 = t[j].pos) : (t[j].pos1 = t[j - 1].pos1 + t[j].pos));
(j == st[i] ? (t[j].pos2 = t[j].pos * t[j].pos) : (t[j].pos2 = t[j - 1].pos2 + t[j].pos * t[j].pos));
}
}
} inline void query(int l , int r , int z)
{
int x = belong[l] , y = belong[r];
if (x == y)
{
for(register int i = l; i <= r; i++)
if (w[i] <= z) m++ , ps1 += pos[i] , ps2 += pos[i] * pos[i];
return;
}
for(register int i = l; i <= ed[x]; i++)
if (w[i] <= z) m++ , ps1 += pos[i] , ps2 += pos[i] * pos[i];
for(register int i = st[y]; i <= r; i++)
if (w[i] <= z) m++ , ps1 += pos[i] , ps2 += pos[i] * pos[i];
int l1 , r1 , mid , ret;
for(register int i = x + 1; i <= y - 1; i++)
{
l1 = st[i] , r1 = ed[i] , ret = 0;
while (l1 <= r1)
{
mid = (l1 + r1) >> 1;
if (t[mid].w <= z) ret = mid , l1 = mid + 1;
else r1 = mid - 1;
}
if (ret) m += ret - st[i] + 1 , ps1 += t[ret].pos1 , ps2 += t[ret].pos2;
}
} int main()
{
freopen("sequence.in" , "r" , stdin);
freopen("sequence.out" , "w" , stdout);
scanf("%d%d" , &n , &q);
for(register int i = 1; i <= n; i++) scanf("%d%lld" , &w[i] , &pos[i]);
parepre();
int x , y , z;
while (q--)
{
scanf("%d%d%d" , &x , &y , &z);
ps1 = ps2 = 0 , m = 0;
query(x , y , z);
if (m == 0)
{
printf("empty\n");
continue;
}
LL k = m * ps2 - ps1 * ps1;
printf("%lld\n" , k);
}
}

JZOJ 4319. 【NOIP2015模拟11.5】Lucas的数列的更多相关文章

  1. [JZOJ 4307] [NOIP2015模拟11.3晚] 喝喝喝 解题报告

    题目链接: http://172.16.0.132/senior/#main/show/4307 题目: 解题报告: 题目询问我们没出现坏对的连续区间个数 我们考虑从左到有枚举右端点$r$,判断$a[ ...

  2. 【NOIP2015模拟11.5】JZOJ8月5日提高组T2 Lucas的数列

    [NOIP2015模拟11.5]JZOJ8月5日提高组T2 Lucas的数列 题目 PS:\(n*n*T*T<=10^{18}\)而不是\(10^1*8\) 题解 题意: 给出\(n\)个元素的 ...

  3. JZOJ 4298. 【NOIP2015模拟11.2晚】我的天

    4298. [NOIP2015模拟11.2晚]我的天 (File IO): input:ohmygod.in output:ohmygod.out Time Limits: 1000 ms Memor ...

  4. 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃

    [NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...

  5. 【NOIP2015模拟11.2晚】JZOJ8月4日提高组T2 我的天

    [NOIP2015模拟11.2晚]JZOJ8月4日提高组T2 我的天 题目 很久很以前,有一个古老的村庄--xiba村,村子里生活着n+1个村民,但由于历届村长恐怖而且黑暗的魔法统治下,村民们各自过着 ...

  6. 【NOIP2015模拟11.4】JZOJ2020年8月6日提高组T2 最优交换

    [NOIP2015模拟11.4]JZOJ2020年8月6日提高组T2 最优交换 题目 题解 题意 有一个长度为\(n\)的正整数 最多可以进行\(k\)次操作 每次操作交换相邻两个位置上的数 问可以得 ...

  7. 【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划

    [NOIP2015模拟11.4]JZOJ8月6日提高组T1 刷题计划 题目 题解 题意 有\(n\)道题,编号为1~\(n\) 给出\(m\)次操作 每次操作有3种类型 1 \(x\) 表示交了\(A ...

  8. 【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行

    [NOIP2015模拟11.5]JZOJ8月5日提高组T3 旅行 题目 若不存在第\(k\)短路径时,输出"Stupid Mike" 题解 题意 给出一个有\(n\)个点的树 问这 ...

  9. 【NOIP2015模拟11.3】备用钥匙

    题目 你知道Just Odd Inventions社吗?这个公司的业务是"只不过是奇妙的发明(Just Odd Inventions)".这里简称为JOI社. JOI社有N名员工, ...

  10. JZOJ4307. 【NOIP2015模拟11.3晚】喝喝喝

    Description

随机推荐

  1. python3实现AES加密

    前言 这几天研究了一下 python 实现 AES 加密,有很多坑 AES 加密的参数及其条件 这个 AES 加密的主要坑就在于这些条件, 首先 aes 加密有一下几个参数 秘钥:加密的时候用秘钥,解 ...

  2. 【大数据-课程】高途-天翼云侯圣文-Day2:离线数仓搭建分解

    一.内容介绍 昨日福利:大数据反杀熟 今日:数据看板 离线分析及DW数据仓库 明日:实时计算框架及全流程 一.数仓定义及演进史 1.概念 生活中解答 2.数据仓库的理解 对比商品仓库 3.数仓分层内容 ...

  3. CCS选择器 选择器优先级 选择器常见属性

    目录 CSS前戏 1.css语法结构 2.css注释语法 3.引入css的多种方式 CSS基本选择器 1.标签选择器 2.类选择器 3.id选择器 4.通用选择器 CSS组合选择器 1.后代选择器(空 ...

  4. 微软出品自动化神器【Playwright+Java】系列(六) 之 字符输入、单元素键盘事件操作、上传文件、聚焦、拖拽、悬浮操作

    前言: 今天一早起床,就一直太阳穴疼,吃了四片去痛片已经无效,真的是疼的直恶心. 如果说学习或者写文章,能够或者头疼的话,那我想说,我还能坚持一会..... 很久没更新这系列的文章了,那么我们将Pla ...

  5. java的饿汉和懒汉设计模式

    本文主要讲述java的饿汉和懒汉设计模式 饿汉和懒汉设计模式的目的:使得该类的对象,只能有一个,不允许其他类,创建该类的对象. 饿汉设计模式 示例代码如下: 1 public class Hunger ...

  6. 中国风?古典系?AI中文绘图创作尝鲜!⛵

    作者:韩信子@ShowMeAI 深度学习实战系列:https://www.showmeai.tech/tutorials/42 本文地址:https://www.showmeai.tech/artic ...

  7. jsvmp_wencai

    网站 aHR0cDovL3d3dy5pd2VuY2FpLmNvbS91bmlmaWVkd2FwL2hvbWUvaW5kZXg= 直接搜索关键词 下面是要抓取的数据 逆向位置(一个即可) hook到he ...

  8. Salesforce LWC学习(四十) datatable的dynamic action的小坑浅谈

    本篇参考:https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/documentatio ...

  9. vue中mixins(混入)的用法

    vue中mixin的使用详解 混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能.一个混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被&quo ...

  10. 20 张图带你全面了解 HTTPS 协议,再也不怕面试问到了!

    本文详细介绍了 HTTPS 相较于 HTTP 更安全的原因,包括对称加密.非对称加密.完整性摘要.数字证书以及 SSL/TLS 握手等内容,图文并茂.理论与实战结合.建议收藏! 1. 不安全的 HTT ...