ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[loj3220]Terytoria

2021-12-18 14:02:49  阅读:135  来源: 互联网

标签:int ll loj3220 swap ans mx Terytoria define


显然两维是独立的,不妨考虑其中一维的答案

将其离散,枚举交包含的某一段(若不存在即交为空),进而即可确定所有段的方向,用线段树维护取到最大值的位置数即可

时间复杂度为$o(n\log n)$,可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 500005
 4 #define ll long long
 5 #define pii pair<int,int>
 6 #define fi first
 7 #define se second
 8 #define L (k<<1)
 9 #define R (L+1)
10 #define mid (l+r>>1)
11 int n,X,Y,M,vis[N],tag[N<<3],mx[N<<3],f[N<<3],dta[N<<1];
12 ll ans;
13 vector<int>v0;
14 vector<pair<int,int> >v;
15 struct Data{
16     int l,r;
17 }x[N],y[N],a[N];
18 void build(int k,int l,int r){
19     if (l==r){
20         mx[k]=n-dta[l],f[k]=v0[l+1]-v0[l];
21         return;
22     }
23     build(L,l,mid),build(R,mid+1,r);
24     mx[k]=max(mx[L],mx[R]),f[k]=0;
25     if (mx[k]==mx[L])f[k]+=f[L];
26     if (mx[k]==mx[R])f[k]+=f[R];
27     mx[k]+=tag[k];
28 }
29 void update(int k,int l,int r,int x,int y,int z){
30     if ((l>y)||(x>r))return;
31     if ((x<=l)&&(r<=y)){
32         tag[k]+=z,mx[k]+=z;
33         return;
34     }
35     update(L,l,mid,x,y,z);
36     update(R,mid+1,r,x,y,z);
37     mx[k]=max(mx[L],mx[R]),f[k]=0;
38     if (mx[k]==mx[L])f[k]+=f[L];
39     if (mx[k]==mx[R])f[k]+=f[R];
40     mx[k]+=tag[k];
41 }
42 void add(int id){
43     if (!vis[id]){
44         tag[1]--,mx[1]--;
45         update(1,0,M,a[id].l,a[id].r-1,2);
46         vis[id]=1;
47     }
48     else{
49         tag[1]++,mx[1]++;
50         update(1,0,M,a[id].l,a[id].r-1,-2);
51         vis[id]=0;
52     }
53 }
54 int calc(int m){
55     v.clear(),v0.clear();
56     memset(vis,0,sizeof(vis));
57     memset(tag,0,sizeof(tag));
58     memset(dta,0,sizeof(dta));
59     for(int i=1;i<=n;i++){
60         v.push_back(make_pair(a[i].l,i));
61         v.push_back(make_pair(a[i].r,i));
62     }
63     sort(v.begin(),v.end());
64     v0.push_back(0);
65     for(int i=0;i<(n<<1);i++)
66         if ((!i)||(v[i].fi!=v[i-1].fi))v0.push_back(v[i].fi);
67     M=v0.size()-1,v0.push_back(m);
68     for(int i=1;i<=n;i++){
69         a[i].l=lower_bound(v0.begin(),v0.end(),a[i].l)-v0.begin();
70         a[i].r=lower_bound(v0.begin(),v0.end(),a[i].r)-v0.begin();
71         dta[a[i].l]++,dta[a[i].r]--;
72     }
73     for(int i=1;i<=M;i++)dta[i]+=dta[i-1];
74     build(1,0,M);
75     int ans=0;
76     for(int i=0;i<(n<<1);i++){
77         add(v[i].se);
78         if (mx[1]==n)ans=max(ans,f[1]);
79     }
80     return ans;
81 }
82 int main(){
83     scanf("%d%d%d",&n,&X,&Y);
84     for(int i=1;i<=n;i++){
85         scanf("%d%d%d%d",&x[i].l,&y[i].l,&x[i].r,&y[i].r);
86         if (x[i].l>x[i].r)swap(x[i].l,x[i].r);
87         if (y[i].l>y[i].r)swap(y[i].l,y[i].r);
88     }
89     memcpy(a,x,sizeof(a));
90     ans=calc(X);
91     memcpy(a,y,sizeof(a));
92     ans*=calc(Y);
93     printf("%lld\n",ans);
94     return 0; 
95 } 
View Code

另外,还有一个更加巧妙的做法:注意到每一个区间的两种选择是互补的,对每一段区间异或一个随机值,那么可以认为众数的出现次数即为答案,这直接排序即可得到

关于错误的概率,并不太会分析,反正大概就对了QAQ

时间复杂度为$o(n\log n)$,也可以通过(比第一种算法常数更小)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 500005
 4 #define ll long long
 5 #define llu unsigned ll
 6 vector<int>v;
 7 int n,X,Y;
 8 ll ans;
 9 llu dta[N<<1];
10 pair<llu,int>P[N];
11 struct Data{
12     int l,r;
13 }x[N],y[N],a[N];
14 llu rnd(){
15     llu x=0;
16     for(int i=0;i<4;i++)x=((x<<16)|rand()%(1<<16));
17     return x;
18 }
19 int calc(int m){
20     v.clear();
21     memset(dta,0,sizeof(dta));
22     for(int i=1;i<=n;i++){
23         v.push_back(a[i].l);
24         v.push_back(a[i].r);
25     }
26     v.push_back(0),v.push_back(m);
27     sort(v.begin(),v.end());
28     for(int i=1;i<=n;i++){
29         a[i].l=lower_bound(v.begin(),v.end(),a[i].l)-v.begin();
30         a[i].r=lower_bound(v.begin(),v.end(),a[i].r)-v.begin();
31         llu p=rnd();
32         dta[a[i].l]^=p,dta[a[i].r]^=p;
33     }
34     for(int i=1;i<=(n<<1);i++)dta[i]^=dta[i-1];
35     for(int i=0;i<=(n<<1);i++)P[i]=make_pair(dta[i],v[i+1]-v[i]);
36     sort(P,P+(n<<1)+1);
37     int cnt=0,ans=0;
38     for(int i=0;i<=(n<<1);i++){
39         cnt+=P[i].second;
40         if ((i==(n<<1))||(P[i+1].first!=P[i].first)){
41             ans=max(ans,cnt);
42             cnt=0;
43         }
44     }
45     return ans;
46 }
47 int main(){
48     srand(time(0));
49     scanf("%d%d%d",&n,&X,&Y);
50     for(int i=1;i<=n;i++){
51         scanf("%d%d%d%d",&x[i].l,&y[i].l,&x[i].r,&y[i].r);
52         if (x[i].l>x[i].r)swap(x[i].l,x[i].r);
53         if (y[i].l>y[i].r)swap(y[i].l,y[i].r);
54     }
55     memcpy(a,x,sizeof(a));
56     ans=calc(X);
57     memcpy(a,y,sizeof(a));
58     ans*=calc(Y);
59     printf("%lld\n",ans);
60     return 0; 
61 } 
View Code

 

标签:int,ll,loj3220,swap,ans,mx,Terytoria,define
来源: https://www.cnblogs.com/PYWBKTDA/p/15704892.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有