• 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;
    }
  • 相关阅读:
    关于ios6.0和5.0的横竖屏支持方法
    windows环境下搭建vue+webpack的开发环境
    诗歌类网址
    【第1阶段—GIS网址清单】其它杂项
    android内存指标
    Rownum与Order by
    使用反射复制一个JavaBean的对象
    catalog
    oralce中rownum理解
    BlockingQueue
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8445133.html
Copyright © 2020-2023  润新知