我是靠谱客的博主 细心背包,最近开发中收集的这篇文章主要介绍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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复