[USACO21DEC] Convoluted Intervals S(复杂区间)

题目描述

奶牛们正在努力尝试发明有趣的新游戏来玩。他们目前的工作之一与一组 \(N\) 个区间(\(1\le N\le 2\cdot 10^5\))有关,其中第 \(i\) 个区间从数轴上的 \(a_i\) 位置开始,并在位置 \(b_i \geq a_i\) 结束。\(a_i\)\(b_i\) 均为 \(0 \ldots M\) 范围内的整数,其中 \(1 \leq M \leq 5000\)

这个游戏的玩法是,Bessie 选择某个区间(假设是第 \(i\) 个区间),而她的表妹 Elsie 选择某个区间(假设是第 \(j\) 个区间,可能与 Bessie 所选的的区间相同)。给定某个值 \(k\),如果 \(a_i + a_j \leq k \leq b_i + b_j\),则她们获胜。

对范围 \(0 \ldots 2M\) 内的每个值 \(k\),请计算使得 Bessie 和 Elsie 可以赢得游戏的有序对 \((i,j)\) 的数量。

输入格式

输入的第一行包含 \(N\)\(M\)。以下 \(N\) 行每行以整数 \(a_i\)\(b_i\) 的形式描述一个区间。

输出格式

输出 \(2M+1\) 行,依次包含范围 \(0 \ldots 2M\) 中的每一个 \(k\) 的答案。

样例输入

2 5
1 3
2 5

样例输出

0
0
1
3
4
4
4
3
3
1
1

样例解释

在这个例子中,对于 \(k=3\),有三个有序对可以使得 Bessie 和 Elsie 获胜:\((1, 1)\)\((1, 2)\),和 \((2, 1)\)

数据范围

  • 测试点 1-2 满足 \(N\le 100, M\le 100\)
  • 测试点 3-5 满足 \(N\le 5000\)
  • 测试点 6-20 没有额外限制。

Solution:

本来以为公式推导优化,发现推不出来

注意到:

\[1 \leq M \leq 5000 \]

\[a_i 和 b_i 均为 0 \ldots M 范围内的整数 \]

可以分别记录\(a_i\)\(b_i\)的出现次数,计算出\(a_i+a_j\)\(b_i+b_j\)的个数,

利用乘法原理进行差分

时间复杂度:\(O(m^2)\)

Code:

#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long ll;

const int M=5005;

int n,m;
int sl[M],sr[M];
ll s[M<<1];

int main()
{
    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;++i)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        sl[l]++;
        sr[r]++;
    }

    for(int i=0;i<=m;++i)
        for(int j=0;j<=m;++j)
        {
            s[i+j]+=(ll)sl[i]*sl[j];
            s[i+j+1]-=(ll)sr[i]*sr[j];
        }
    for(int i=0;i<=2*m;++i)s[i]+=s[i-1];
    
    for(int i=0;i<=2*m;++i)
        printf("%lld\n",s[i]);
    return 0;
}
posted @ 2022-10-04 15:55  FighterQ  阅读(59)  评论(0)    收藏  举报