Gym 101908C - Pizza Cutter - [樹狀數組]

題目連接:https://codeforces.com/gym/101908/problem/Cc++

 

題意:數組

一塊正方形披薩,有 $H$ 刀是橫切的,$V$ 刀是豎切的,不存在大於等於三條直線交於一點。求最後切出多少片披薩。優化

 

題解:spa

橫切和豎切分開考慮,若是橫切的直線之間有 $ans_1$ 個交點,豎切的直線之間有 $ans_2$ 個交點,那麼最後答案就是 $(H+1)(V+1)+ans_1+ans_2$。code

這裏求交點個數,是用的一種比較常見的樹狀數組優化的套路。blog

還有就是時限比較緊,用vector作離散化被卡了,改用數組就行了。get

 

AC代碼:it

#include<bits/stdc++.h>
#define mk make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+10;

int X,Y;
int H,V;

int v[2*maxn],tot;
inline int getID(int x)
{
    return lower_bound(v,v+tot,x)-v+1;
}

struct Line{
    int l,r;
    bool operator<(const Line& o)const {
        return l>o.l;
    }
}lines[maxn];

struct _BIT{
    int N,C[2*maxn];
    inline int lowbit(int x){return x&(-x);}
    void init(int n) //初始化共有n個點
    {
        N=n;
        for(int i=1;i<=N;i++) C[i]=0;
    }
    void add(int pos,int val) //在pos點加上val
    {
        while(pos<=N)
        {
            C[pos]+=val;
            pos+=lowbit(pos);
        }
    }
    int ask(int pos) //查詢1~pos點的和
    {
        int ret=0;
        while(pos>0)
        {
            ret+=C[pos];
            pos-=lowbit(pos);
        }
        return ret;
    }
}BIT;

ll solve(int UP)
{
    BIT.init(tot+3);
    ll res=0;
    for(int i=1;i<=UP;i++)
    {
        res+=(ll)BIT.ask(lines[i].r-1);
        BIT.add(lines[i].r,1);
    }
    return res;
}

int main()
{
    scanf("%d%d%d%d",&X,&Y,&H,&V);

    tot=0;
    for(int i=1;i<=H;++i)
    {
        scanf("%d%d",&lines[i].l,&lines[i].r);
        v[tot++]=lines[i].l;
        v[tot++]=lines[i].r;
    }
    sort(v,v+tot); unique(v,v+tot);
    for(int i=1;i<=H;i++) lines[i].l=getID(lines[i].l), lines[i].r=getID(lines[i].r);
    sort(lines+1,lines+H+1);
    ll ans1=solve(H);

    tot=0;
    for(int i=1;i<=V;i++)
    {
        scanf("%d%d",&lines[i].l,&lines[i].r);
        v[tot++]=lines[i].l;
        v[tot++]=lines[i].r;
    }
    sort(v,v+tot); unique(v,v+tot);
    for(int i=1;i<=V;i++) lines[i].l=getID(lines[i].l), lines[i].r=getID(lines[i].r);
    sort(lines+1,lines+V+1);
    ll ans2=solve(V);

    printf("%I64d\n",((ll)H+1LL)*((ll)V+1LL)+ans1+ans2);
}
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息