洛谷P1102 A-B数对

双指针做法:

 

 反过来,从后往前看也是一样的:

复制代码
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cmath>
#define For(i, j, n) for (int i = j; i <= n; ++i)
using namespace std;

const int N = 2e5 + 5;

int n, c;
int a[N];

int main()
{
    scanf("%d%d", &n, &c);
    For(i, 1, n)
        scanf("%d", a + i);
    sort(a + 1, a + n + 1);
    /*for (int i = 1; i <= n; i++)
        cout << i << " ";
    puts("");
    for (int i = 1; i <= n; i++)
        cout << a[i] << " ";
    cout << endl;*/
    // int r1 = 1, r2 = 1;
    long long ans = 0;
    /*for(int i = 1; i <= n; i++)
    {
        int k = a[i] + c;
        while(r1 <= n && a[r1] < k) r1++;
        while(r2 <= n && a[r2] <= k) r2++;
        if(a[r1] == k && a[r2 - 1] == k)
            ans += r2 - r1;
    }*/
    int l1 = 1, l2 = 1;
    for(int i = 1; i <= n; i++)
    {
        int k = a[i] - c;
        while(l1 <= n && a[l1] < k) l1++;
        while(l2 <= n && a[l2] <= k) l2++;
        if(a[l1] == k && l2 >= 2 && a[l2 - 1] == k)
            ans += l2 - l1; 
    }
    printf("%lld\n", ans);
    return 0;
}
复制代码

另外要注意的是,这道题虽然N只有1e5数量级,但ans还是需要开long long的,我们可以分析一下ans的范围:

考虑最极端的情况:

a[]由一系列相等的部分连接而成:

如1 1 1 1 1 …… 2 2 2 2 2 

我们简化一下情况,假设每一段数字的数量都相同且为k,那么ans就是:

nk×k2=nk

(为了方便,不考虑向下取整)

我们令k=n/2,就可以让ans来到n^2数量级,从而爆int

 

本文作者:smartljy

本文链接:https://www.cnblogs.com/smartljy/p/18107119

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Gold_stein  阅读(6)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 逃离地面 RAD & 三浦透子
逃离地面 - RAD & 三浦透子
00:00 / 00:00
An audio error has occurred.

作词 : 野田洋次郎

作曲 : 野田洋次郎

空飛ぶ羽根と引き換えに 繋ぎ合う手を選んだ僕ら

それでも空に魅せられて 夢を重ねるのは罪か

夏は秋の背中を見て その顔を思い浮かべる

憧れなのか、恋なのか 叶わぬと知っていながら

重力が眠りにつく 1000年に一度の今日

太陽の死角に立ち 僕らこの星を出よう

彼が眼を覚ました時 連れ戻せない場所へ

「せーの」で大地を蹴って ここではない星へ

行こう

もう少しで運命の向こう もう少しで文明の向こう

もう少しで運命の向こう もう少しで

夢に僕らで帆を張って 来たるべき日のために夜を超え

いざ期待だけ満タンで あとはどうにかなるさと 肩を組んだ

怖くないわけない でも止まんない

ピンチの先回りしたって 僕らじゃしょうがない

僕らの恋が言う 声が言う

「行け」と言う