我是靠谱客的博主 细心背包,这篇文章主要介绍2019 Multi-University Training Contest 9 Rikka with Cake(离散化做法和动态开点做法)Rikka with Cake,现在分享给大家,希望可以做个参考。
Rikka with Cake
答案线段相交个数加1
扫描线求交点个数
离散化做法:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116#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); } }
动态开点做法:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77#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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复