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
  • 相关阅读:
    pycharm下载与安装
    IOS 字体表
    iOS 在 ARC 环境下 dealloc 的使用、理解误区
    微信支付的开发
    Undefined symbols for architecture i386:和"_OBJC_CLASS_$_xx", referenced from:问题解决方法
    soureTree使用
    UINavigationController 直接pop到指定controllerView的方法
    OBC: NSString 与 NSArray 互转
    NSArray的containsObject的使用时注意的问题
    IOS 自定义导航栏标题和返回按钮标题
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13875305.html
Copyright © 2011-2022 走看看