ACdream 1157 Segments(cdq分治)

来源:互联网 发布:慈溪行知职高地址全称 编辑:程序博客网 时间:2024/06/05 05:08

学习了merge函数。
参考题解:http://blog.csdn.net/v5zsq/article/details/51083826
在ACdream上留下了一页半的wa和tle这里写图片描述

总体来说,思路并不难。插入一条线段,就是在线段的起点+1,删除一条线段,就是-1,查询就是+0。在分治的时候,按照线段右端点降序排序。对于左区间的点,更新左端点所在位置。右区间的线段,查询左端点的前缀和统计。如果能像51nod那样查看数据就好了,调代码就方便多了。也不知道哪里写错了,模仿人家的代码写了一发。把离散化的方式换成我比较习惯的方式了。。。。

#include <bits/stdc++.h>using namespace std;#define lowbit(x) (x&(-x))const int MAXN = 220022;int n,tot;struct node{    int x,y,cnt,id,ans;    bool operator<(const node& a) const    {        return y > a.y;    }} p[MAXN],q[MAXN];bool cmpid(const node& a, const node& b){    return a.id < b.id;}int bit[MAXN];void add(int x, int v){    while(x <= tot)    {        bit[x] += v;        x += lowbit(x);    }}int sum(int x){    int ret = 0;    while(x)    {        ret += bit[x];        x -= lowbit(x);    }    return ret;}void CDQ(int l, int r){    if(l >= r) return;    int mid = (l+r) >> 1;    CDQ(l,mid);    CDQ(mid+1,r);    sort(p+l,p+mid+1);    sort(p+mid+1,p+r+1);    int j = l;    for(int i = mid+1; i <= r; ++i)    {        for(; j <= mid && p[j].y >= p[i].y; ++j)            add(p[j].x,p[j].cnt);        if(!p[i].cnt)            p[i].ans += sum(p[i].x);    }    for(int i = l; i < j; ++i)        add(p[i].x,-p[i].cnt);    merge(p+l,p+mid+1,p+mid+1,p+r+1,q);    for(int i = 0; i < r-l+1; ++i)        p[l+i]=q[i];}int res,l[MAXN],r[MAXN];vector<int> vec;int getid(int x){    return lower_bound(vec.begin(),vec.end(),x)-vec.begin()+1;}int main(){    while(scanf("%d",&n) != EOF)    {        vec.clear();        memset(bit,0,sizeof(bit));        res = 1;        for(int i = 1; i <= n; ++i)        {            p[i].id = i;            p[i].ans = 0;            char s;            int temp;            scanf(" %c",&s);            if(s == 'D')            {                scanf("%d %d",&p[i].x,&p[i].y);                p[i].cnt = 1;                l[res] = p[i].x;                r[res++] = p[i].y;                vec.push_back(p[i].x);                vec.push_back(p[i].y);            }            else if(s == 'Q')            {                scanf("%d %d",&p[i].x,&p[i].y);                p[i].cnt = 0;                vec.push_back(p[i].x);                vec.push_back(p[i].y);            }            else            {                scanf("%d",&temp);                p[i].x = l[temp];                p[i].y = r[temp];                p[i].cnt = -1;            }        }        sort(vec.begin(),vec.end());        vec.erase(unique(vec.begin(),vec.end()),vec.end());        tot = vec.size();        for(int i = 1; i <= n; ++i)        {            p[i].x = getid(p[i].x);            p[i].y = getid(p[i].y);        }        CDQ(1,n);        sort(p+1,p+1+n,cmpid);        for(int i = 1; i <= n; ++i)            if(!p[i].cnt)                printf("%d\n",p[i].ans);    }    return 0;}
原创粉丝点击