令$nex_{i}=\min_{i<j,p_{i}<p_{j}}j$(即$i$的第2类边),若不存在此类$j$则$nex_{i}=n+1$

建一棵树,其以0为根,且$1\le i\le n$的父亲为$\max_{j<i,p_{i}<p_{j}}j$(不存在则为0),以下记作$fa_{i}$

每一次选择$(i,nex_{i})$,都可以看作有一个收益$\Delta_{i}=b_{i}-\sum_{j=i}^{nex_{i}-1}a_{j}$

问题也可以看作选择若干个节点$p_{1}<p_{2}<...<p_{k}$,使得$nex_{p_{i}}\le p_{i+1}$且$(p_{i},nex_{p_{i}})$与$S$无公共点,在此条件下最小化$\sum_{i=1}^{k}\Delta_{p_{i}}+\sum_{i=1}^{n}a_{i}$(后者为常数,以下忽略)

考虑$(i,nex_{i})$,实际上这些点恰为以$i$为根的子树中的点(不包括$i$)

(注意这棵树中,若$i$为$j$的祖先,则必然有$i<j$)

由此,条件也即变为$p_{i}$之间两两不成祖先-后代关系,且$p_{i}$子树内(不包括$p_{i}$)不能含有$S$中的点

(关于这两点性质,可以简单分类讨论地分析一下,具体这里就省略了)

令$f_{i}$表示以$i$为根的子树内,选择若干个两两不成祖先-后代关系的点,$\sum\Delta_{p_{i}}$之和的最大值(忽略$S$的限制),对于$f$显然可以树形dp计算,复杂度为$o(n)$

问题即求所有极浅的点,满足其子树内(不包括自己)没有$S$中的元素,这些点的$f$之和

更具体的,令$H$为包含0以及$S$中所有元素的父亲的最小连通块,“满足其子树内(不包括自己)没有$S$中的元素”即等价于不在$H$中,因此问题即求$\sum_{x\notin H,fa_{x}\in H}f_{x}$

令$g_{x}=\sum_{fa_{y}=x}f_{y}$,枚举$fa_{x}$并用$g_{x}$减去$x\in H$的部分,即求$\sum_{x\in H}(g_{x}-\sum_{fa_{y}=x,y\in H}f_{y})$

将两部分拆开,也即$\sum_{x\in H}g_{x}-\sum_{x\in H,x\ne 0}f_{x}=g_{0}+\sum_{x\in H,x\ne 0}g_{x}-f_{x}$(前者为常数,以下忽略)

令$i$到$fa_{i}$的边权为$g_{i}-f_{i}$,也即求$H$中所有边权之和

考虑将0以及$S$中所有元素的父亲按照dfs序排序,依次为$p_{1},p_{2},...,p_{k}$,答案即$\frac{\sum_{i=1}^{k}dis(p_{i},p_{i\ mod\ k+1})}{2}$

(关于这个的正确性,这样从$p_{1}->p_{2}->...->p_{k}$,$H$中每一条边必然被经过恰好两次)

关于这个,用线段树或set维护即可,复杂度为$o((n+q)\log n)$

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define ll long long
5 #define L (k<<1)
6 #define R (L+1)
7 #define mid (l+r>>1)
8 struct Edge{
9 int nex,to;
10 }edge[N];
11 int E,n,q,x,p[N],head[N],st[N],dfn[N],idfn[N],sh[N],vis[N],fa[N][21],f[N<<2];
12 ll sum,ans,a[N],b[N],g[N],dp[N],dep[N];
13 void add(int x,int y){
14 edge[E].nex=head[x];
15 edge[E].to=y;
16 head[x]=E++;
17 }
18 int lca(int x,int y){
19 if (sh[x]<sh[y])swap(x,y);
20 for(int i=20;i>=0;i--)
21 if (sh[fa[x][i]]>=sh[y])x=fa[x][i];
22 if (x==y)return x;
23 for(int i=20;i>=0;i--)
24 if (fa[x][i]!=fa[y][i]){
25 x=fa[x][i];
26 y=fa[y][i];
27 }
28 return fa[x][0];
29 }
30 ll dis(int x,int y){
31 return dep[x]+dep[y]-2*dep[lca(x,y)];
32 }
33 ll dis_dfn(int x,int y){
34 return dis(idfn[x],idfn[y]);
35 }
36 void dfs1(int k){
37 for(int i=head[k];i!=-1;i=edge[i].nex){
38 dfs1(edge[i].to);
39 g[k]+=dp[edge[i].to];
40 }
41 dp[k]=min(g[k],b[k]);
42 }
43 void dfs2(int k,int f,int s1,ll s2){
44 idfn[x]=k;
45 dfn[k]=x++;
46 sh[k]=s1;
47 dep[k]=s2;
48 fa[k][0]=f;
49 for(int i=1;i<=20;i++)fa[k][i]=fa[fa[k][i-1]][i-1];
50 for(int i=head[k];i!=-1;i=edge[i].nex)dfs2(edge[i].to,k,s1+1,s2+g[edge[i].to]-dp[edge[i].to]);
51 }
52 void update(int k,int l,int r,int x,int y){
53 f[k]+=y;
54 if (l==r)return;
55 if (x<=mid)update(L,l,mid,x,y);
56 else update(R,mid+1,r,x,y);
57 }
58 int query(int k,int l,int r,int x){
59 if (l==r)return f[k];
60 if (x<=mid)return query(L,l,mid,x);
61 return query(R,mid+1,r,x);
62 }
63 int query_pre(int k,int l,int r,int x){
64 if ((!f[k])||(l>x))return -1;
65 if (l==r)return l;
66 int ans=query_pre(R,mid+1,r,x);
67 if (ans>=0)return ans;
68 return query_pre(L,l,mid,x);
69 }
70 int query_nex(int k,int l,int r,int x){
71 if ((!f[k])||(r<x))return -1;
72 if (l==r)return l;
73 int ans=query_nex(L,l,mid,x);
74 if (ans>=0)return ans;
75 return query_nex(R,mid+1,r,x);
76 }
77 int query_pre(int x){
78 int ans=query_pre(1,0,n,x-1);
79 if (ans>=0)return ans;
80 return query_pre(1,0,n,n);
81 }
82 int query_nex(int x){
83 int ans=query_nex(1,0,n,x+1);
84 if (ans>=0)return ans;
85 return query_nex(1,0,n,0);
86 }
87 ll calc(int k){
88 int x=query_pre(k),y=query_nex(k);
89 return dis_dfn(x,k)+dis_dfn(y,k)-dis_dfn(x,y);
90 }
91 int main(){
92 scanf("%d%d",&n,&q);
93 for(int i=1;i<=n;i++)scanf("%d",&p[i]);
94 for(int i=1;i<=n;i++){
95 scanf("%lld",&a[i]);
96 a[i]+=a[i-1];
97 }
98 for(int i=1;i<=n;i++)scanf("%lld",&b[i]);
99 for(int i=n;i;i--){
100 while ((st[0])&&(p[st[st[0]]]<p[i]))st[0]--;
101 if (!st[0])b[i]-=a[n]-a[i-1];
102 else b[i]-=a[st[st[0]]-1]-a[i-1];
103 st[++st[0]]=i;
104 }
105 memset(head,-1,sizeof(head));
106 st[0]=0;
107 for(int i=1;i<=n;i++){
108 while ((st[0])&&(p[st[st[0]]]<p[i]))st[0]--;
109 add(st[st[0]],i);
110 st[++st[0]]=i;
111 }
112 dfs1(0);
113 dfs2(0,0,0,0);
114 sum=g[0]+a[n];
115 update(1,0,n,0,1);
116 for(int i=1;i<=q;i++){
117 scanf("%d",&x);
118 int y=dfn[fa[x][0]];
119 if (!vis[x]){
120 update(1,0,n,y,1);
121 if (query(1,0,n,y)==1)ans+=calc(y);
122 }
123 else{
124 update(1,0,n,y,-1);
125 if (!query(1,0,n,y))ans-=calc(y);
126 }
127 vis[x]^=1;
128 printf("%lld\n",sum+ans/2);
129 }
130 }

[cf1495F]Squares的更多相关文章

  1. [LeetCode] Word Squares 单词平方

    Given a set of words (without duplicates), find all word squares you can build from them. A sequence ...

  2. 卡通图像变形算法(Moving Least Squares)附源码

    本文介绍一种利用移动最小二乘法来实现图像变形的方法,该方法由用户指定图像中的控制点,并通过拖拽控制点来驱动图像变形.假设p为原图像中控制点的位置,q为拖拽后控制点的位置,我们利用移动最小二乘法来为原图 ...

  3. Leetcode: Word Squares && Summary: Another Important Implementation of Trie(Retrieve all the words with a given Prefix)

    Given a set of words (without duplicates), find all word squares you can build from them. A sequence ...

  4. [LintCode] Perfect Squares 完全平方数

    Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 1 ...

  5. HDU 1264 Counting Squares(线段树求面积的并)

    Counting Squares Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. RSS(Residual Sum of Squares)的自由度为什么是n-1呢

    [转载请注明出处]http://www.cnblogs.com/mashiqi 在回归问题中,偶尔我们会遇到求方差的估计的情况.举了例子,我们常常通过Gaussian分布${\cal N}(\mu , ...

  7. poj-3739. Special Squares(二维前缀和)

    题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. ...

  8. [CareerCup] 7.5 A Line Cut Two Squares in Half 平均分割两个正方形的直线

    7.5 Given two squares on a two-dimensional plane, find a line that would cut these two squares in ha ...

  9. POJ 2002 Squares

    二分.... Squares Time Limit: 3500MS Memory Limit: 65536K Total Submissions: 14530 Accepted: 5488 Descr ...

随机推荐

  1. 题解 [HNOI2007]分裂游戏

    题目传送门 题目大意 有趣的取石子游戏即将开始. 有 \(n\) 堆石头,编号为 \(0,1,2,...,n-1\).两个人轮流挑石头. 在每个回合中,每个人选择三堆编号为 \(i,j,k\) 的石头 ...

  2. Dapr + .NET Core实战(十四)虚拟机集群部署 mDNS + Consul

    前面我们说了在单机模式下和K8S集群下的Dapr实战,这次我们来看看如何在不使用K8S的情况下,在一个传统的虚拟机集群里来部署Dapr. 1.环境准备 我们准备两台centos7虚拟机 Dapr1:1 ...

  3. mysql join语句的执行流程是怎么样的

    mysql join语句的执行流程是怎么样的 join语句是使用十分频繁的sql语句,同样结果的join语句,写法不同会有非常大的性能差距. select * from t1 straight_joi ...

  4. NX Open显示符号(UF_DISP_display_temporary_point)

    UF_DISP_display_temporary_point 使用方法: 1 Dim x As Double = 0, y As Double = 0, z As Double = 0 2 3 Di ...

  5. 2020年09月15日-项目开发-python二次处理代码文件

    Caterpillar通过将BPMN生成为solidity代码后, 我需要对solidity代码做二次处理,即在其中的特定函数中插入event类型,以便去做事件监听. 最终生成的不仅包括solidit ...

  6. docker内服务访问宿主机服务

    目录 1. 场景 2. 解决 4. 参考 1. 场景 使用windows, wsl2 进行日常开发测试工作. 但是wsl2经常会遇到网络问题.比如今天在测试一个项目,核心功能是将postgres 的数 ...

  7. Python小工具:据说这是搜索文件最快的工具!没有之一!一起感受下......

    电脑自带的搜索文件功能相信大家都体验过,那是真的慢,等它找到文件,我都打完一把游戏了! 那必须不能忍,于是我自己做了一个文件搜索工具,犄角旮旯的文件都能一秒钟搜索出来的那种! 保证能把你们男(女)朋友 ...

  8. Coursera Deep Learning笔记 结构化机器学习项目 (下)

    参考:https://blog.csdn.net/red_stone1/article/details/78600255https://blog.csdn.net/red_stone1/article ...

  9. seata整合多数据源

    seata整合多数据源 一.背景 二.整合步骤 1.seata server的搭建 2.引入数据源切换组件 3.引入seata组件 4.配置多数据源 5.关闭seata自己默认的数据源代理 6.配置s ...

  10. 2021.8.9考试总结[NOIP模拟34]

    T1 Merchant 如果$t=0$时不能达到$s$,那么所拿物品的价值一定关于时间单调递增,答案单调.因此可以特判$0$后二分. 用$sort$复杂度被卡,要用$\textit{nth_eleme ...