• [loj3220]Terytoria


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

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

    时间复杂度为$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
  • 相关阅读:
    <COM原理和应用>第七章的ITextObject代码是什么?
    CString转换成char*
    COM的永久接口
    复合文档实现结构化存储的一些限制
    COM结构化存储中存储对象或者流对象的命名规则
    VS2008:Failed to return new Code Element
    MFC COM调用时出现E_OUTOFMEMORY错误
    红米NOTE应用闪退(包括系统设置等各种界面)问题解决经历
    C++中用完需要释放掉内存的几个类
    QT For Android 运行的时候找不到手机怎么办?
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15704892.html
Copyright © 2020-2023  润新知