ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

cogs2479 偏序(CDQ套CDQ)

2019-02-17 08:50:35  阅读:266  来源: 互联网

标签:偏序 int mid cogs2479 while cdq2 CDQ include


题目链接

思路

四维偏序
\(CDQ\)套\(CDQ\),第一维默认有序。第二维用第一个CDQ变成有序的。并且对每个点标记上第一维属于左边还是右边。第二个\(CDQ\)处理第三维,注意两个\(CDQ\)不能用同一个数组,否则第二维就变成无序的了。最后一维用个树状数组统计答案。

代码

/*
* @Author: wxyww
* @Date:   2019-02-16 16:39:12
* @Last Modified time: 2019-02-17 08:18:59
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 50010;
ll read() {
    ll x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
int n;
struct node {
    int a,b,c,d,opt;
}a[N],tmp[N],tt[N];
bool cmp(const node &x,const node &y) {
    return x.a <= y.a;
}
int tree[N];
int mx;
void update(int pos,int c) {
    while(pos <= mx) {
        tree[pos] += c;
        pos += pos & -pos;
    }
}
int query(int pos) {
    int ret = 0;
    while(pos) {
        ret += tree[pos];
        pos -= pos & -pos;
    }
    return ret;
}
vector<int>v;
int ans;
void cdq2(int l,int r) {
    if(r <= l) return;
    int mid = (l + r) >> 1;
    cdq2(l,mid);
    cdq2(mid + 1,r);
    int L = l,R = mid + 1,now = l;
    while(L <= mid && R <= r) {
        if(tmp[L].c < tmp[R].c) {
            if(tmp[L].opt == 1) update(tmp[L].d,1),v.push_back(tmp[L].d);
            tt[now++] = tmp[L++];
        }
        else {
            if(tmp[R].opt == 2) ans += query(tmp[R].d - 1);
            tt[now++] = tmp[R++];
        }
    }
    while(L <= mid) tt[now++] = tmp[L++];
    while(R <= r) {
        if(tmp[R].opt == 2) ans += query(tmp[R].d - 1);
        tt[now++] = tmp[R++];
    }
    for(int i = l;i <= r;++i) tmp[i] = tt[i];
    int k = v.size();
    for(int i = 0;i < k;++i) update(v[i],-1);
    v.clear();
}
void cdq(int l,int r) {
    if(r <= l) return;
    int mid = (l + r) >> 1;
    cdq(l,mid);
    cdq(mid + 1,r);
    int L = l,R = mid + 1,now = l;
    while(L <= mid && R <= r) { 
        if(a[L].b < a[R].b) tmp[now] = a[L++],tmp[now++].opt = 1;
        else tmp[now] = a[R++],tmp[now++].opt = 2;
    }
    while(L <= mid) tmp[now] = a[L++],tmp[now++].opt = 1;
    while(R <= r) tmp[now] = a[R++],tmp[now++].opt = 2;
    for(int i = l;i <= r;++i) a[i] = tmp[i];
    cdq2(l,r);
}
int main() {
    n = read();
    for(int i = 1;i <= n;++i) mx = max(mx,(a[i].a = i));
    for(int i = 1;i <= n;++i) mx = max(mx,(a[i].b = read()));
    for(int i = 1;i <= n;++i) mx = max(mx,(a[i].c = read()));
    for(int i = 1;i <= n;++i) mx = max(mx,(a[i].d = read()));
    cdq(1,n);
    cout<<ans;
    return 0;
}

标签:偏序,int,mid,cogs2479,while,cdq2,CDQ,include
来源: https://www.cnblogs.com/wxyww/p/cogs2479.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有