2019 Multi-University Training Contest 9 Rikka with Cake(離散化做法和動態開點做法)

Rikka with Cake

答案線段相交個數加1

掃描線求交點個數

離散化做法:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll powmod(ll a,ll b) {ll res=1;
for(;b;b>>=1){if(b&1)res=res*a;a=a*a;}return res;}
const int N=2e5+10;
int sum[N*4];
int x,y;
char ch1[2],ch;
struct node
{
    int x,y,f;
    bool operator <(const node &o)const
    {
        if(x==o.x) return f<o.f;
        return x<o.x;
    }
}b[N*4];
int Y[N*2];
int cnt,len,cnt1;

void up(int id,int l,int r,int pos,int val)
{
    if(l==r){
        sum[id]+=val;
        return ;
    }
    int mid=l+r>>1;
    if(pos<=mid) up(id<<1,l,mid,pos,val);
    else up(id<<1|1,mid+1,r,pos,val);
    sum[id]=sum[id<<1]+sum[id<<1|1];
}
int qu(int id,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr)
    {
        return sum[id];
    }
    int ans=0;
    int mid=l+r>>1;
    if(ql<=mid) ans+=qu(id<<1,l,mid,ql,qr);
    if(qr>mid) ans+=qu(id<<1|1,mid+1,r,ql,qr);
    return ans;
}

int getid(int x)
{
    return lower_bound(Y+1,Y+1+len,x)-Y;
}
int main()
{
    int _;
    scanf("%d",&_);
    while(_--)
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        cnt=0,len=0;
        for(int i=1;i<=k;++i)
        {
            scanf("%d%d%s",&x,&y,ch1);
            ch=ch1[0];
            Y[++len]=y;
            if(ch=='U') b[++cnt]=(node){x,y,2};
            else if(ch=='D') b[++cnt]=(node){x,y,3};
            else if(ch=='L')
            {
                b[++cnt]=(node){x,y,4};
                b[++cnt]=(node){0,y,1};
            }
            else if(ch=='R')
            {
                b[++cnt]=(node){x,y,1};
                b[++cnt]=(node){n,y,4};
            }
        }
        Y[++len]=0;
        Y[++len]=m;
        sort(b+1,b+1+cnt);
        sort(Y+1,Y+1+len);
        len=unique(Y+1,Y+1+len)-Y-1;
        int ans=0;
        for(int i=1;i<=cnt;++i)
        {
            if(b[i].f==1)
            {
                int id=getid(b[i].y);
                up(1,1,len,id,1);
            }
            else if(b[i].f==4){
                int id=getid(b[i].y);
                up(1,1,len,id,-1);
            }
            else{
                int l,r;
                if(b[i].f==2)
                {
                    l=getid(b[i].y);
                    r=len;
                }
                else{
                    l=1;
                    r=getid(b[i].y);
                }
                if(l>r) swap(l,r);
                ans+=qu(1,1,len,l,r);
            }
        }
        printf("%d\n",ans+1);
    }
}

動態開點做法:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,k;
int ls[N*40],rs[40*N],sum[40*N],rt,inde,cnt;
struct node
{
    int x,y,f;
    bool operator <(const node &o)const
    {
        if(x==o.x) return f<o.f;
        return x<o.x;
    }
}b[N*2];
void up(int &o,int l,int r,int pos,int val)
{
    if(!o) o=++inde;
    sum[o]+=val;
    if(l==r) return ;
    int mid=l+r>>1;
    if(pos<=mid) up(ls[o],l,mid,pos,val);
    else     up(rs[o],mid+1,r,pos,val);
}
int qu(int o,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr) return sum[o];
    int mid=l+r>>1;
    int ans=0;
    if(ql<=mid) ans+=qu(ls[o],l,mid,ql,qr);
    if(qr>mid)ans+=qu(rs[o],mid+1,r,ql,qr);
    return ans;
}
int main()
{
    int _;
    cin>>_;
    while(_--)
    {
        scanf("%d%d%d",&n,&m,&k);
        cnt=0;
        rt=0;
        for(int i=1;i<=k;++i)
        {
            int x,y;
            char ch[2];
            scanf("%d%d%s",&x,&y,ch);
            if(ch[0]=='U') b[++cnt]=(node){x,y,2};
            else if(ch[0]=='D') b[++cnt]=(node){x,y,3};
            else if(ch[0]=='L')
            {
                b[++cnt]=(node){x,y,4};
                b[++cnt]=(node){0,y,1};
            }
            else if(ch[0]=='R')
            {
                b[++cnt]=(node){x,y,1};
                b[++cnt]=(node){n,y,4};
            }
            //up(rt, 1, m, y, 1);
        }
        sort(b+1,b+1+cnt);
        int ans=0;
        for(int i=1;i<=cnt;++i)
        {
            if(b[i].f==1) up(rt,1,m,b[i].y,1);
            else if(b[i].f==4) up(rt,1,m,b[i].y,-1);
            else
            {
                if(b[i].f==3) ans+=qu(rt,1,m,1,b[i].y);
                else ans+=qu(rt,1,m,b[i].y,m);
            }
        }
        printf("%d\n",ans+1);
        for(int i=1;i<=inde;++i) ls[i]=rs[i]=sum[i]=0;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章