2019杭电多校第9场1002 Rikka with Cake HDU6681

6 篇文章 0 订阅
2 篇文章 0 订阅

2019杭电多校第9场1002 Rikka with Cake HDU6681

题意:给你若干个点按上下左右切割平面,最后问平面内有几块被切割开来。

解法1:红黑树+思维+贪心

A:根据欧拉定理可以得出(具体参照题解),平面内有多少个交点,那么就有这么多个+1的平面被分割出来,所以这题目就是找点。
B:将U,D,L,R分开来存在四个结构体中,然后分类讨论U和L相交的点数,U和R相交的点数,D和L相交的点数,D和R相交的点数,最后相加再+1就是答案。
C:在讨论的时候。举例(U和L相交)。按着l[i]的x从小到大排序,u[i]的x从小到大排序,然后遍历l,找l[i]能和几条向上的线相交。我们可以知道相交必然意味着,u[j]的x比l[i]的小,同时我们要找在这几个中有几个u[j]的y坐标小于l[i].y,最后全部相加。这样就讨论完了一处情况。
D:关于上面C黄字的处理,利用红黑树,正好插入一个值与查询有几个小于的复杂都是log(n),然后不停插入,然后比较相加就完事了。

解法2:树状数组+思维+贪心

A:早上看了一下题解发现树状数组也能做,贴一个树状数组的解法吧,其实和上面的解法很像,就是把(D过程)红黑树改成树状数组就OK了。
B:两者代码的不同也很明显,我直接在我的红黑树上改了一下,具体可以看代码2。

闲话123:关于红黑树,我这里偷懒使用超级STL库来实现了。比赛的时候,想了很久主席树该怎么实现,写到吐血。。最后发现了有pb_ds这个神奇的东西,最后花了30分钟写题目,WA了三发。。。最后赛后刚把题目放出来就A了,真赛后三分钟A题,谢队友不杀。

PS:超级STL库只能在clion里面运行,辣鸡VS2019

解法1代码1


#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace __gnu_pbds;
using namespace std;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> rbtree;
typedef long long ll;
ll n,m,k;
const int mx = 3e5+7;
struct node
{
    ll x, y;
}u[mx],d[mx],l[mx],r[mx];
bool cmp(node a,node b) {
    return a.x < b.x;
}
int main (){
    ios_base::sync_with_stdio(false);
    rbtree stlnb;
    int t;
    cin >> t;
    while (t--) {
        cin >> n >> m >> k;
        ll cnt[6] = { 0 };
        for (int i = 1; i <= k; i++) {
            ll x, y; char s;
            cin>>x>>y>>s;
            if (s == 'U')
                u[++cnt[1]].x = x, u[cnt[1]].y = y;
            else if (s == 'D')
                d[++cnt[2]].x = x, d[cnt[2]].y = y;
            else if (s == 'L')
                l[++cnt[3]].x = x, l[cnt[3]].y = y;
            else if (s == 'R')
                r[++cnt[4]].x = x, r[cnt[4]].y = y;
        }
        sort(u + 1, u + 1 + cnt[1], cmp);
        sort(d + 1, d + 1 + cnt[2], cmp);
        sort(l + 1, l + 1 + cnt[3], cmp);
        sort(r + 1, r + 1 + cnt[4], cmp);
        ll sumn = 0;
        ll f = 1;
        for (int i = 1; i <= cnt[3]; i++) {
            for (int j = f; j <= cnt[1]; j++) {
                f = j+1;
                if (l[i].x >= u[j].x)
                    stlnb.insert(u[j].y);
                else {
                    f = j;
                    break;
                }
            }
            sumn += stlnb.order_of_key(l[i].y);
        }
        stlnb.clear();
        f = cnt[1];
        for (int i = cnt[4]; i >= 1; i--) {
            for (int j = f; j >= 1; j--) {
                f = j-1;
                if (r[i].x <= u[j].x)
                    stlnb.insert(u[j].y);
                else {
                    f = j;
                    break;
                }
            }
            sumn += stlnb.order_of_key(r[i].y);
        }
        stlnb.clear();
        f = 1;
        for (int i = 1; i <= cnt[3]; i++) {
            for (int j = f; j <= cnt[2]; j++) {
                f = j+1;
                if (l[i].x >= d[j].x)
                    stlnb.insert(d[j].y);
                else {
                    f = j;
                    break;
                }
            }
            sumn += stlnb.size() - stlnb.order_of_key(l[i].y);
        }
        stlnb.clear();
        f = cnt[2];
        for (int i = cnt[4]; i >= 1; i--) {
            for (int j = f; j >= 1; j--) {
                f = j-1;
                if (r[i].x <= d[j].x)
                    stlnb.insert(d[j].y);
                else {
                    f = j;
                    break;
                }
            }
            sumn += stlnb.size() -stlnb.order_of_key(r[i].y);
        }
        stlnb.clear();
        cout<<sumn+1<<endl;
    }
    return 0;
}

解法2代码


#include <functional>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll n,m,k;
const int mx = 3e5+7;
const ll wa = 1e9+7;
struct node
{
    ll x, y;
    ll qx,qy;
}u[mx],d[mx],l[mx],r[mx];
ll ssx[mx],ssy[mx];
bool cmp(node a,node b) {
    return a.x < b.x;
}
int bit[mx];
int lowbit(int x)
{
    return x&(-x);
}
void add(int i,int x)
{
    while(i<=k)
    {
        bit[i]+=x;
        i+=lowbit(i);
    }
}
void sub(int i,int x)
{
    while(i<=k)
    {
        bit[i]-=x;
        i+=lowbit(i);
    }
}
int sum(int i)
{
    int s=0;
    while(i>0)
    {
        s+=bit[i];
        i-=lowbit(i);
    }
    return s;
}

int main (){
    ios_base::sync_with_stdio(false);
#ifdef ACM_LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int t;
    cin >> t;
    while (t--) {
        cin >> n >> m >> k;
        ll cnt[6] = { 0 };
        for (int i = 1; i <= k; i++) {
            ll x, y; char s;
            cin>>x>>y>>s;
            if (s == 'U')
                u[++cnt[1]].x = x, u[cnt[1]].y = y;
            else if (s == 'D')
                d[++cnt[2]].x = x, d[cnt[2]].y = y;
            else if (s == 'L')
                l[++cnt[3]].x = x, l[cnt[3]].y = y;
            else if (s == 'R')
                r[++cnt[4]].x = x, r[cnt[4]].y = y;
            ssx[i] = x;
            ssy[i] = y;
        }
        sort(ssx+1,ssx+1+k);
        sort(ssy+1,ssy+1+k);
        sort(u + 1, u + 1 + cnt[1], cmp);
        sort(d + 1, d + 1 + cnt[2], cmp);
        sort(l + 1, l + 1 + cnt[3], cmp);
        sort(r + 1, r + 1 + cnt[4], cmp);
        ll sumn = 0;
        ll f = 1;
        for (int i = 1; i <= cnt[3]; i++) {
            for (int j = f; j <= cnt[1]; j++) {
                f = j+1;
                if (l[i].x >= u[j].x) {
                    int sr = lower_bound(ssy+1,ssy+1+k,u[j].y)-ssy;
                    add(sr,1);
                    //stlnb.insert(u[j].y);
                }
                else {
                    f = j;
                    break;
                }
            }
            //sumn += stlnb.order_of_key(l[i].y);
            sumn+=sum(lower_bound(ssy+1,ssy+1+k,l[i].y)-ssy);
        }
        //stlnb.clear();
        memset(bit,0,sizeof(bit));
        f = cnt[1];
        for (int i = cnt[4]; i >= 1; i--) {
            for (int j = f; j >= 1; j--) {
                f = j-1;
                if (r[i].x <= u[j].x)
                    add(lower_bound(ssy+1,ssy+1+k,u[j].y)-ssy,1);//stlnb.insert(u[j].y);
                else {
                    f = j;
                    break;
                }
            }
          // sumn += stlnb.order_of_key(r[i].y);
          sumn += sum(lower_bound(ssy+1,ssy+1+k,r[i].y)-ssy);
        }
        //stlnb.clear();
        memset(bit,0,sizeof(bit));
        f = 1;
        ll ssr = 0;
        for (int i = 1; i <= cnt[3]; i++) {
            for (int j = f; j <= cnt[2]; j++) {
                f = j+1;
                if (l[i].x >= d[j].x)
                    add(lower_bound(ssy+1,ssy+1+k,d[j].y)-ssy,1),ssr++;//stlnb.insert(d[j].y);
                else {
                    f = j;
                    break;
                }
            }
            //sumn += stlnb.size() - stlnb.order_of_key(l[i].y);
            sumn += ssr - sum(lower_bound(ssy+1,ssy+1+k,l[i].y)-ssy);
        }
        //stlnb.clear();
        memset(bit,0,sizeof(bit));
        ssr = 0;
        f = cnt[2];
        for (int i = cnt[4]; i >= 1; i--) {
            for (int j = f; j >= 1; j--) {
                f = j-1;
                if (r[i].x <= d[j].x)
                    add(lower_bound(ssy+1,ssy+1+k,d[j].y)-ssy,1),ssr++;//stlnb.insert(d[j].y);
                else {
                    f = j;
                    break;
                }
            }
            //sumn += stlnb.size() -stlnb.order_of_key(r[i].y);
            sumn += ssr - sum(lower_bound(ssy+1,ssy+1+k,r[i].y)-ssy);;
        }
        //stlnb.clear();
        memset(bit,0,sizeof(bit));
        cout<<sumn+1<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值