洛谷 P6006 [USACO20JAN]Farmer John Solves 3SUM G

Problem

什么是3-SUM?

给你一个序列\(a\),求有多少组\((i,j,k)(1\le i<j<k\le n)\)满足\(a_i+a_j+a_k=0\).

这是一个有名的算法问题,尚未发现比运行速度比平方时间明显更优的解法。

这道题给你一个长度为\(n(n\le5000)\)的序列,之后有\(q(q\le10^6)\)个询问,查询你区间\([l,r]\)的\(3-SUM\)的答案。

Solution

当你看到题目描述的时候,可能会想那位Farmer John的重大突破是啥。但是你只要知道怎么\(O(n^2)\),再想想这个\(O(n^2)\)能不能预处理,然后用更低的时间复杂度查询就好。(别以为真的有啥接近线性的算法)

首先怎么\(O(n^2)\)做呢?

枚举两个变量,对当前的第三个变量的能取的范围预先开好一个桶计数。这样我们就固定了两个变量\(i,j\),去桶里面找\(-a_i-a_j\)的数量即可。

如果你是枚举\(i,j\),对k的取值范围\([j+1,n]\)开桶的话,当然也可以但是这个k的限制并不显然(或者是也有向下做的方法只是我没有想到吧)

如果我们枚举\(i,k\),这样\(k\)的取值范围就是\([i+1,k-1]\)。记\(c_x\)表示在当前区间内,等于\(x\)的\(a_k\)的数量;设\(f_{i,k}\)表示选定左端点为\(i\),右端点为\(k\)时的3-SUM​方案数。

for(int i=1;i<=n;i++)
{
c[a[i+1]+M]++;
for(int k=i+2;k<=n;k++)
{
if(a[i]+a[k]<=M&&a[i]+a[k]>=-M) f[i][k]+=c[M-a[i]-a[k]];
c[a[k]+M]++;
}
c[a[i+1]+M]--;
for(int k=i+2;k<=n;k++)
{
c[a[k]+M]--;//clear
}
}

代码中的c是桶,M可以先不管(见下文)

对于一个询问\((l,r)\),这里的\(i,k\)当然可以选\([l,r]\)中的任意值(只要满足\(i<k\))。这不就是求

\[\sum_{i=l}^r\sum_{k=i+1}^r f_{i,k}
\]

这部分可以用二维前缀和预处理出来。

这样对于每一个询问都可以\(O(1)\)回答了。

需要注意的地方

不需要在求二维前缀和的时候判断\(i<k\)(准确说是\(i<\dots<k\Rightarrow i+1<k\)),因为不合法部分的\(f_{i,k}\)依然是\(0\).

即直接预处理

\[sum_{l,r}=\sum_{i=l}^r\sum_{k=l}^r f_{i,k}
\]

对于每个询问用二维前缀和的差分

\[ans_{l,r}=sum_{r,r}-sum_{r,l-1}-sum_{l-1,r}+sum_{l-1,l-1}
\]

就好了。

以及注意值域有负数,所以桶的大小要开两倍并且给所有的数都加上一个\(10^6\)

Code

/**************************************************************
* Problem: 6006
* Author: Vanilla_chan
* Date: 20210307
**************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<limits.h>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#ifdef TH
#define debug printf("Now is %d\n",__LINE__);
#else
#define debug
#endif
#ifdef ONLINE_JUDGE
char buf[1<<23],* p1=buf,* p2=buf,obuf[1<<23],* O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
using namespace std; template<class T>inline void read(T& x)
{
char ch=getchar();
int fu;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)) { x=x*10+ch-'0';ch=getchar(); }
x*=fu;
}
inline int read()
{
int x=0,fu=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)) { x=x*10+ch-'0';ch=getchar(); }
return x*fu;
}
int G[55];
template<class T>inline void write(T x)
{
int g=0;
if(x<0) x=-x,putchar('-');
do { G[++g]=x%10;x/=10; } while(x);
for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
}
#define N 6010
int n,q;
int a[N];
LL f[N][N];
int c[2000010];
#define M 1000000
int main()
{
n=read();
q=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++)
{
c[a[i+1]+M]++;
for(int k=i+2;k<=n;k++)
{
if(a[i]+a[k]<=M&&a[i]+a[k]>=-M) f[i][k]+=c[M-a[i]-a[k]];
c[a[k]+M]++;
}
c[a[i+1]+M]--;
for(int k=i+2;k<=n;k++)
{
c[a[k]+M]--;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
}
}
int x,y;
while(q--)
{
x=read();
y=read();
if(x>y) swap(x,y);
write(f[y][y]-f[x-1][y]-f[y][x-1]+f[x-1][x-1]);
}
return 0;
}

洛谷 P6006 [USACO20JAN]Farmer John Solves 3SUM G的更多相关文章

  1. 洛谷 P2882 [USACO07MAR]Face The Right Way G

    题目传送门 题目描述 Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing ...

  2. 洛谷P2891 Dining P1402 酒店之王【类二分图匹配】题解+代码

    洛谷P2891 Dining P1402 酒店之王[类二分图匹配]题解+代码 酒店之王 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的 ...

  3. 洛谷 P1596 [USACO10OCT]湖计数Lake Counting

    题目链接 https://www.luogu.org/problemnew/show/P1596 题目描述 Due to recent rains, water has pooled in vario ...

  4. 洛谷 [USACO17OPEN]Bovine Genomics G奶牛基因组(金) ———— 1道骗人的二分+trie树(其实是差分算法)

    题目 :Bovine Genomics G奶牛基因组 传送门: 洛谷P3667 题目描述 Farmer John owns NN cows with spots and NN cows without ...

  5. 洛谷P2982 [USACO10FEB]慢下来Slowing down(线段树 DFS序 区间增减 单点查询)

    To 洛谷.2982 慢下来Slowing down 题目描述 Every day each of Farmer John's N (1 <= N <= 100,000) cows con ...

  6. 洛谷 1938 [USACO09NOV]找工就业Job Hunt

    洛谷 1938  [USACO09NOV]找工就业Job Hunt 题目描述 Bessie is running out of money and is searching for jobs. Far ...

  7. 洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game

    洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game 题目描述 Bessie is playing a number game against Farmer John, ...

  8. 【洛谷】P2880 [USACO07JAN]平衡的阵容Balanced Lineup(st表)

    题目背景 题目描述: 每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连 ...

  9. 洛谷 P3659 [USACO17FEB]Why Did the Cow Cross the Road I G

    //神题目(题目一开始就理解错了)... 题目描述 Why did the cow cross the road? Well, one reason is that Farmer John's far ...

  10. [洛谷P2852] [USACO06DEC]牛奶模式Milk Patterns

    洛谷题目链接:[USACO06DEC]牛奶模式Milk Patterns 题目描述 Farmer John has noticed that the quality of milk given by ...

随机推荐

  1. VScode美化

    RESULT:EVA-初号机 配色 主题效果 1. 需要的东西 vs code background 插件 custom CSS and JS loader 插件 一些png素材,推荐网址: http ...

  2. Linux 安装配置Anaconda

    下载地址 https://www.anaconda.com/download/success 选择系统版本,复制链接 wget https://repo.anaconda.com/archive/An ...

  3. WARN  Issues with peer dependencies found,pnpm peer dependencies auto-install

    前言 pnpm 也需要设置自动安装对等依赖项 解决 pnpm 使用 npm 的配置格式,所以应该以与 npm 相同的方式设置配置: pnpm config set auto-install-peers ...

  4. linux ln命令详解

    介绍 ln是linux的一个重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在 ...

  5. Delphi字符串加密解密函数

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  6. 【Docker】镜像

    Docker 镜像 是什么 UnionFS(联合文件系统) UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层(layer).轻量级并且高性能的文件系统,它支持对文件系统的 ...

  7. 【Web】支持纯静态的Layuimini版本

    支持纯静态的Layuimini版本 本人做了点小小的改动,在来的基础上添加了对静态的支持. 零.起因 要做个项目,但是用的是JSP,想着用Layui,然后去找模板,发现这个Layuimini.但是这个 ...

  8. Golang高性能引擎:ZKmall开源商城支撑百万级日活交易流畅运行

    在电商业务高并发.低延迟的严苛场景下,技术栈的选择直接决定系统上限.ZKmall开源商城基于Golang技术生态,以协程级并发.毫秒级响应为核心优势,为百万级日活电商平台提供高性能解决方案.本文从架构 ...

  9. 探秘Transformer系列之(23)--- 长度外推

    探秘Transformer系列之(23)--- 长度外推 目录 探秘Transformer系列之(23)--- 长度外推 0x00 概述 0x01 背景 1.1 问题 1.2 解决思路 1.3 微调的 ...

  10. Mybatis三大执行器

    目录 1.执行器介绍 执行器的选择入口 设置执行器两种方式 全局配置(不建议) 局部设置(建议) 2.三个执行器区别 SimpleExecutor ReuseExecutor BatchExecuto ...