bzoj2441 [中山市选2011]小W的问题(debug中)

2441: [中山市选2011]小W的问题

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 487  Solved: 186
[Submit][Status][Discuss]

Description

有一天,小W找了一个笛卡尔坐标系,并在上面选取了N个整点。他发现通过这些整点能够画出很多个“W”出来。具体来说,对于五个不同的点(x1, y1), (x2, y2), (x3, y3), (x4, y4), (x5, y5),如果满足:

·x1 < x2 < x3 < x4 < x5

·y1 > y3 > y2

·y5 > y3 > y4

则称它们构成一个“W”形。

现在,小W想统计“W”形的个数,也就是满足上面条件的五元点组个数。你能帮助他吗?

Input

    第一行包含一个整数N,表示点的个数。

下面N行每行两个整数,第i+1行为(xi, yi),表示第i个点的坐标。

Output

仅包含一行,为“W”形个数模1 000 000 007的值

Sample Input

6

1 10

2 1

3 5

4 6

5 1

6 10

Sample Output

3

HINT 

对于100%的数据满足N ≤ 200 000,0 ≤ xi ≤ 10^9,0 ≤ yi ≤ 10^9

Source

Day2

开始做这道题的时候还是正中午,现在......

这题真的是烦,如果横纵坐标不相等,还好点,现在相等了,直接gg.

两个思路,一是统计下面几种图形的数量:

,容斥一下就好了.我写了横纵坐标不相等的代码,但是一旦横纵坐标相等就gg.

另外的思路是借鉴的网上其他题解的.

结果两份代码都没debug成功QAQ,省选前我会回来填坑的.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll maxn = 200010,mod = 1000000007,inf = 2000000000;

struct node
{
    ll x,y,x2,id;
}e[maxn];

int n;
ll ans1[maxn],ans2[maxn],b[maxn],sum[maxn << 2],L[maxn << 2],R[maxn << 2],tag[maxn << 2],ans,tot;

bool cmp(node a,node b)
{
    return a.y < b.y;
}

bool cmp2(node a,node b)
{
    return a.x < b.x;
}

void pushup(int o)
{
    sum[o] = sum[o * 2] + sum[o * 2 + 1];
    sum[o] %= mod;
}

void build(int o,int l,int r)
{
    L[o] = l,R[o] = r;
    sum[o] = tag[o] = 0;
    if (l == r)
        return;
    int mid = (l + r) >> 1;
    build(o * 2,l,mid);
    build(o * 2 + 1,mid + 1,r);
    pushup(o);
}

void pushdown(int o)
{
    if (tag[o])
    {
        tag[o * 2] += tag[o];
        tag[o * 2] %= mod;
        tag[o * 2 + 1] += tag[o];
        tag[o * 2 + 1] %= mod;
        sum[o * 2] += tag[o] * (R[o * 2] - L[o * 2] + 1) % mod;
        sum[o * 2 + 1] += tag[o] * (R[o * 2 + 1] - L[o * 2 + 1] + 1) % mod;
        tag[o] = 0;
    }
}

void update(int o,int l,int r,int x,int y,int v)
{
    if (x > y)
        return;
    if (x <= l && r <= y)
    {
        sum[o] += (r - l + 1) * 1LL * v % mod;
        sum[o] %= mod;
        tag[o] += v;
        tag[o] %= mod;
        return;
    }
    pushdown(o);
    int mid = (l + r) >> 1;
    if (x <= mid)
        update(o * 2,l,mid,x,y,v);
    if (y > mid)
        update(o * 2 + 1,mid + 1,r,x,y,v);
    pushup(o);
}

void update2(int o,int l,int r,int pos,int v)
{
    if (l == r)
    {
        //sum[o] += v;
        //sum[o] %= mod;
        //tag[o] += v;
        //tag[o] %= mod;
        sum[o] = v;
        return;
    }
    pushdown(o);
    int mid = (l + r) >> 1;
    if (pos <= mid)
        update2(o * 2,l,mid,pos,v);
    else
        update2(o * 2 + 1,mid + 1,r,pos,v);
    pushup(o);
}

ll query(int o,int l,int r,int x,int y)
{
    if (x > y)
        return 0;
    if (x <= l && r <= y)
        return sum[o];
    pushdown(o);
    ll res = 0;
    int mid = (l + r) >> 1;
    if (x <= mid)
        res += query(o * 2,l,mid,x,y);
    res %= mod;
    if (y > mid)
        res += query(o * 2 + 1,mid + 1,r,x,y);
    res %= mod;
    return res;
}

void solve1()
{
    build(1,1,n);
    for (int i = 1; i <= n; i++)
    {
        int j = i;
        while (j < n && e[i].y == e[j + 1].y)
            j++;
        for (int k = i; k <= j; k++)
            update(1,1,n,e[k].x2,n,-1);
        for (int k = i; k <= j; k++)
            ans1[e[k].id] = query(1,1,n,1,e[k].x - 1);
        for (int k = i; k <= j; k++)
            update2(1,1,n,e[k].id,e[k].x - 1);
        i = j;
    }
}

void solve2()
{
    build(1,1,n);
    for (int i = 1; i <= n; i++)
    {
        int j = i;
        while (j < n && e[i].y == e[j + 1].y)
            j++;
        for (int k = i; k <= j; k++)
            update(1,1,n,1,e[k].x - 1,-1);
        for (int k = i; k <= j; k++)
            ans2[e[k].id] = query(1,1,n,e[k].x2,n);
        for (int k = i; k <= j; k++)
            update2(1,1,n,e[k].id,n - e[k].x2 + 1);
        i = j;
    }
}

int main()
{
    scanf("%d",&n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld%lld",&e[i].x,&e[i].y);
        b[++tot] = e[i].x;
    }
    b[++tot] = inf;
    sort(b + 1,b + 1 + tot);
    sort(e + 1,e + 1 + n,cmp2);
    for (int i = 1; i <= n; i++)
    {
        e[i].x2 = upper_bound(b + 1,b + 1 + tot,e[i].x) - b;
        e[i].x = lower_bound(b + 1,b + 1 + tot,e[i].x) - b;
        e[i].id = i;
    }
    sort(e + 1,e + 1 + n,cmp);
    solve1();
    sort(e + 1,e + 1 + n,cmp);
    solve2();
    /*
    for (int i = 1; i <= n; i++)
    {
        printf("%lld %lld
",ans1[i],ans2[i]);
        ans += ans1[i] * ans2[i] % mod;
        ans %= mod;
    }
    */
    printf("%lld
",ans);

    return 0;
}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll maxn = 200010,mod = 1000000007,inf = 2000000000;

struct node
{
    ll x,y,x2,id;
}e[maxn];

ll n;
ll ans1[maxn],ans2[maxn],b[maxn],sum[maxn << 2],L[maxn << 2],R[maxn << 2],tag[maxn << 2],ans,tot;

bool cmp(node a,node b)
{
    return a.y < b.y;
}

bool cmp2(node a,node b)
{
    return a.x < b.x;
}

void pushup(ll o)
{
    sum[o] = sum[o * 2] + sum[o * 2 + 1];
    sum[o] %= mod;
}

void build(ll o,ll l,ll r)
{
    L[o] = l,R[o] = r;
    sum[o] = tag[o] = 0;
    if (l == r)
        return;
    ll mid = (l + r) >> 1;
    build(o * 2,l,mid);
    build(o * 2 + 1,mid + 1,r);
    pushup(o);
}

void pushdown(ll o)
{
    if (tag[o])
    {
        tag[o * 2] += tag[o];
        tag[o * 2] %= mod;
        tag[o * 2 + 1] += tag[o];
        tag[o * 2 + 1] %= mod;
        sum[o * 2] += tag[o] * (R[o * 2] - L[o * 2] + 1) % mod;
        sum[o * 2 + 1] += tag[o] * (R[o * 2 + 1] - L[o * 2 + 1] + 1) % mod;
        tag[o] = 0;
    }
}

void update(ll o,ll l,ll r,ll x,ll y,ll v)
{
    if (x > y)
        return;
    if (x <= l && r <= y)
    {
        sum[o] += (r - l + 1) * 1LL * v % mod;
        sum[o] %= mod;
        tag[o] += v;
        tag[o] %= mod;
        return;
    }
    pushdown(o);
    ll mid = (l + r) >> 1;
    if (x <= mid)
        update(o * 2,l,mid,x,y,v);
    if (y > mid)
        update(o * 2 + 1,mid + 1,r,x,y,v);
    pushup(o);
}

void update2(ll o,ll l,ll r,ll pos,ll v)
{
    if (l == r)
    {
        sum[o] = v;
        return;
    }
    pushdown(o);
    ll mid = (l + r) >> 1;
    if (pos <= mid)
        update2(o * 2,l,mid,pos,v);
    else
        update2(o * 2 + 1,mid + 1,r,pos,v);
    pushup(o);
}

ll query(ll o,ll l,ll r,ll x,ll y)
{
    if (x > y)
        return 0;
    if (x <= l && r <= y)
        return sum[o];
    pushdown(o);
    ll res = 0;
    ll mid = (l + r) >> 1;
    if (x <= mid)
        res += query(o * 2,l,mid,x,y);
    res %= mod;
    if (y > mid)
        res += query(o * 2 + 1,mid + 1,r,x,y);
    res %= mod;
    return res;
}

void solve1()
{
    build(1,1,n);
    for (ll i = 1; i <= n; i++)
    {
        ll j = i;
        while (j < n && e[i].y == e[j + 1].y)
            j++;
        for (ll k = i; k <= j; k++)
            update(1,1,n,e[k].x2,n,-1);
        for (ll k = i; k <= j; k++)
            ans1[e[k].id] = query(1,1,n,1,e[k].x - 1);
        for (ll k = i; k <= j; k++)
            update2(1,1,n,e[k].id,e[k].x - 1);
        i = j;
    }
}

void solve2()
{
    build(1,1,n);
    for (ll i = 1; i <= n; i++)
    {
        ll j = i;
        while (j < n && e[i].y == e[j + 1].y)
            j++;
        for (ll k = i; k <= j; k++)
            update(1,1,n,1,e[k].x - 1,-1);
        for (ll k = i; k <= j; k++)
            ans2[e[k].id] = query(1,1,n,e[k].x2,n);
        for (ll k = i; k <= j; k++)
            update2(1,1,n,e[k].id,n - e[k].x2 + 1);
        i = j;
    }
}

int main()
{
    scanf("%d",&n);
    for (ll i = 1; i <= n; i++)
    {
        scanf("%lld%lld",&e[i].x,&e[i].y);
        b[++tot] = e[i].x;
    }
    b[++tot] = inf;
    sort(b + 1,b + 1 + tot);
    sort(e + 1,e + 1 + n,cmp2);
    for (ll i = 1; i <= n; i++)
    {
        e[i].x2 = upper_bound(b + 1,b + 1 + tot,e[i].x) - b;
        e[i].x = lower_bound(b + 1,b + 1 + tot,e[i].x) - b;
        e[i].id = i;
    }
    sort(e + 1,e + 1 + n,cmp);
    solve1();
    sort(e + 1,e + 1 + n,cmp);
    solve2();
    for (ll i = 1; i <= n; i++)
    {
        ans += ans1[i] * ans2[i] % mod;
        ans %= mod;
    }

    printf("%lld
",ans);

    return 0;
}
原文地址:https://www.cnblogs.com/zbtrs/p/8445133.html