我是靠谱客的博主 细心背包,最近开发中收集的这篇文章主要介绍2019 Multi-University Training Contest 9 Rikka with Cake(离散化做法和动态开点做法)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("%dn",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("%dn",ans+1);
        for(int i=1;i<=inde;++i) ls[i]=rs[i]=sum[i]=0;
    }
}

 

最后

以上就是细心背包为你收集整理的2019 Multi-University Training Contest 9 Rikka with Cake(离散化做法和动态开点做法)Rikka with Cake的全部内容,希望文章能够帮你解决2019 Multi-University Training Contest 9 Rikka with Cake(离散化做法和动态开点做法)Rikka with Cake所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部