没做出来,上网看人家的题解后终于明白了。
其实做的时候也发觉了,这应该是一道差分题。但是究竟应该如何差分呢?对什么进行差分呢?搞不明白。
在这道题中,我们可以O(n^2)的计算出所有的一个区间的覆盖。
但是,两个区间的话怎么比较他们的最大值呢?
总不能O(m)的一一对照吧!那样的话就O(n^2m)不行!
所以该怎么办呢?
看了大佬的博客,发现大佬维护了这么一个东西sub[i][j]
意为:有两个k区间一个是以i为开头一个是以j为开头
以i为开头的区间因为以j为开头的区间而减去的贡献。
为什么要维护这个东西呢?
因为事实上,在我们计算m中每一个区间对当前k区间的贡献度的时候,我们是可以计算出比此时贡献度小的k区间在哪里,比此时贡献度大的k区间在哪里。
这些区间具有连续性,我们可以用差分维护。

但是困难来了。如果两个区间的贡献度相同呢?
我们当然也算,那么在减去的时候其实就是减去双倍了。
所以,对于整体我们都要维护双倍。
这里的差分极为讲究!!!

#include<iostream>
#include<algorithm>
using namespace std;
int n,m,k;
int lft[2100],rgt[2100];
int res[2100],sub[2100][2100];
void Solve(int l){
    int r = l+k-1;
    for (int i=1;i<=m;++i){
        int a = min(r,rgt[i])-max(l,lft[i])+1;
        a=max(a,0);res[l]+=a;

        if (a == k||a == rgt[i]-lft[i]+1){
            sub[l][max(1,lft[i]+a-k)]+=a;
            sub[l][rgt[i]-a+2]-=a;
        }
        else{
            sub[l][max(1,lft[i]+a-k)]+=a;
            sub[l][max(1,lft[i]+a-k+1)]+=a;
            sub[l][rgt[i]-a+1]-=a;
            sub[l][rgt[i]-a+2]-=a;
        }
    }for (int i=1;i+k-1<=n;++i)sub[l][i]+=sub[l][i-1];
}
int main(){
    scanf("%d %d %d",&n,&m,&k);
    for (int i=1;i<=m;++i)
        scanf("%d %d",&lft[i],&rgt[i]);
    for (int i=1;i+k-1<=n;++i)
        Solve(i);

    int ans = 0;
    for (int i=1;i+k-1<=n;++i)
        for (int j=i;j+k-1<=n;++j)
            ans = max(ans,res[i]+res[j]-(sub[i][j]+sub[j][i])/2);
    printf("%d\n",ans);
}