CDQ分治-------luoguP2345 [USACO04OPEN]MooFest G题解

题目链接:(https://www.luogu.com.cn/problem/P2345)

这道题大多数人的解法是根据v来进行排序,而我则是用的排序x的方法,看见还没人发就来发一篇.(这道题数据真滴水啊)

解题步骤

首先我们可以看到,题目中给的是许多奶牛的坐标和听力值,我们很容易联想到把其中中一个元素进行排序,这样子就可以只用考虑其中的一个元素了 然而我解这道题的时候联系到了三值偏序问题,(将a作为第一关键字排序后再用归并排须排序b值的时候无论怎么变换,在范围[l,mid]里面的a值都会小于范围[mid+1,r]中的a值,然后就是骚操作来了),所以我就排序了奶牛的坐标

接着我又利用归并排须,排序v的同时计算出答案

具体解题细节

首先:一定要记得开longlong

答案的计算公式

解释一下:大家应该都知道归并排序的原理,就是两个序列进行合并。而在此算法中第一个序列的“x”数值一定小于任意一个第二个序列的“x”数值

rt记录的就是目前已经被合并的第二序列的数的“x”数值之和

lt记录的就是目前已经被合并的第一序列的数的“x”数值之和

t1表示的就是目前到了序列一的第几个位置了,t1-l就是当前节点减去起点就是已经合并的序列1的数的个数

然后t2表示的就是目前到了序列2的第几个位置了,t2-mid-1就是当前节点减去起点就是已经合并的序列2的数的个数

1.res+=T[t1].v*(rt-(t2-mid-1)*T[t1].x),t1++;//如果当前节点是归并排序中属于序列1合并来的,那么它的x一定比已经合并的属于序列2的数的x值小,

//                                          对于任意的序列1中的“x”数值一定小于序列二中的数值,所以任意序列2中的“x”数值减去序列1中的 “x”数值一定大于0,

//                                          同时又因为序列2中的每一个数都要减去当前这个合并进去的数的“x”数值,

//                                      所以直接用目前已经被合并的第二序列的数的“x”数值之和减去已经合并的序列2的数的个数与当前点的“x”数值的乘积就行了

2.res+=T[t2].v*((t1-l)*T[t2].x-lt),t2++;//如果是当前节点在归并排序中属于序列2合并来的,那么它的x一定比前面的大,上面解释的很详细,不赘述了。

 

(还有就是我在此处通过一点点的推断可以去除绝对值,具体见答案计算以及上面提到的“在范围[l,mid]里面的a值都会小于范围[mid+1,r]中的a值”)

CODE

#include <bits/stdc++.h>
using namespace std;
#define int long long 
struct node{int v,x;}T[20005],b[20005];
int n,res=0;
int cmp(node A,node B){
    if(A.x != B.x)return A.x<B.x;
    return A.v<B.v;
}
int CDQ(int l , int r){
    if(l == r)return 0;
    int mid=(l+r)>>1;
    CDQ(l,mid);CDQ(mid+1,r);
    int t1=l,t2=mid+1,lt=0,rt=0;
    for (int i = l ; i <= r ; i ++){
        if(T[t1].v <= T[t2].v && t1 <= mid || t2 > r )
        b[i]=T[t1],lt+=T[t1].x,//合并序列的同时计算答案
        res+=T[t1].v*(rt-(t2-mid-1)*T[t1].x),t1++;
        else b[i]=T[t2],rt+=T[t2].x,
        res+=T[t2].v*((t1-l)*T[t2].x-lt),t2++;;
    }
    for (int i = l ; i <= r ; i ++)T[i]=b[i];
    return 0;
}
signed main(){
    cin>>n;
    for (int i = 1 ; i <= n ; i ++)
    cin>>T[i].v>>T[i].x;
    sort(T+1,T+1+n,cmp);
    CDQ(1,n);
    cout<<res;
    return 0;
}
 
原文地址:https://www.cnblogs.com/MYCui/p/13535251.html