zoukankan      html  css  js  c++  java
  • [loj3277]星座3

    如果不合法,利用贪心发现当且仅当某两个星星所构成的矩形中没有白点

    反过来,考虑留下若干个星星,那么即要求留下的星星两两之间满足:$max_{x_{1}le ile x_{2}}a_{i}ge min(y_{1},y_{2})$

    考虑笛卡尔树,那么在笛卡尔树上这等价于使得两点lca的高度大于等于两点最低高度,由于$a_{fa}ge a_{k}$($fa$为$k$在lca上的父亲),因此这又等价于要求以$k$为根的子树中最多只能保留1个数比$a_{k}$大

    令$f[i][j]$表示以$i$为根的子树中最高不超过为$j$且合法的最大保留的价值,其合法状态数量为不超过子树中点数量,因此启发式合并即可维护,时间复杂度为$o(nlog^{2}n)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define ll long long
     5 set<pair<ll,ll> >::iterator it;
     6 set<pair<ll,ll> >s[N];
     7 int n,m,x,y,z,a[N],st[N],ls[N],rs[N],f[N];
     8 long long ans,mx[N],tag[N];
     9 int find(int k){
    10     if (k==f[k])return k;
    11     return f[k]=find(f[k]);
    12 }
    13 void merge(int x,int y,int k){
    14     x=find(x),y=find(y);
    15     while ((s[y].size())&&((*s[y].begin()).first<=k)){
    16         mx[y]=max(mx[y],(*s[y].begin()).second+tag[y]);
    17         s[y].erase(s[y].begin());
    18     }
    19     if (s[x].size()<s[y].size()){
    20         f[x]=y;
    21         swap(x,y);
    22     }
    23     tag[x]+=mx[y];
    24     tag[y]+=mx[x];
    25     mx[x]+=mx[y];
    26     for(it=s[y].begin();it!=s[y].end();it++)
    27         s[x].insert(make_pair((*it).first,(*it).second+tag[y]-tag[x]));
    28 }
    29 void dfs(int k){
    30     if (!k)return;
    31     dfs(ls[k]);
    32     dfs(rs[k]);
    33     merge(k,ls[k],a[k]);
    34     merge(k,rs[k],a[k]);
    35 }
    36 int main(){
    37     scanf("%d",&n);
    38     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    39     for(int i=1;i<=n;i++)f[i]=i;
    40     for(int i=1;i<=n;i++){
    41         while ((st[0])&&(a[st[st[0]]]<a[i]))ls[i]=st[st[0]--];
    42         if (st[0])rs[st[st[0]]]=i;
    43         st[++st[0]]=i;
    44     }
    45     scanf("%d",&m);
    46     for(int i=1;i<=m;i++){
    47         scanf("%d%d%d",&x,&y,&z);
    48         s[x].insert(make_pair(y,z));
    49         ans+=z;
    50     }
    51     dfs(st[1]);
    52     x=find(st[1]);
    53     for(it=s[x].begin();it!=s[x].end();it++)mx[x]=max(mx[x],tag[x]+(*it).second);
    54     printf("%lld",ans-mx[x]);
    55 } 
    View Code
  • 相关阅读:
    AngularJS Insert Update Delete Using PHP MySQL
    Simple task manager application using AngularJS PHP MySQL
    AngularJS MySQL and Bootstrap Shopping List Tutorial
    Starting out with Node.js and AngularJS
    AngularJS CRUD Example with PHP, MySQL and Material Design
    How to install KVM on Fedora 22
    Fake_AP模式下的Easy-Creds浅析
    河南公务员写古文辞职信
    AI
    政协委员:最大愿望是让小学生步行上学
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13875305.html
Copyright © 2011-2022 走看看