首页 > 其他分享 >Codeforces 1495F - Squares

Codeforces 1495F - Squares

时间:2023-06-06 18:33:44浏览次数:37  
标签:nxt get int Codeforces 1495F MAXN vec Squares suma

不知道怎么放到 div1F 的,感觉没啥亮点。

首先对于一条 \(1\) 到 \(n+1\) 的路径而言,它经过的点的编号一定是递增的,也就是说,如果我们将关键点大小排个序,那么答案就是相邻两点间最短路的和。删 / 加点造成的变化是 \(O(1)\) 的,所以问题等价于,多次询问这张图中 \(x,y\) 之间最短路的值。

先假设 \(x\to y\) 全部走 \(a_i\) 的边,那么每一次走 \(i\to nxt_i\) 的边的变化相当于令答案扣除 \(\sum\limits_{j=i}^{nxt_i-1}a_j\) 再加上 \(b_i\),由于我们走 \(i\to nxt_i\) 的边所对应的 \([i,nxt_i)\) 不能相交并且必须要满足 \(x\le i<nxt_i\le y\),因此问题可以转化为,有 \(n\) 个形如 \([i,nxt_i-1]\) 的区间,带权,要求 \([x,y]\) 最大权不交区间集的权值。

朴素的做法是树状数组优化 DP,放在这里左端点不固定当然行不通。但是这个图的性质我们还没用。非常重要的一个性质是不存在 \(i<j<nxt_i<nxt_j\),也就是任意两个区间如果有交,则它们是包含关系。考虑这样一个算法,从大到小枚举 \(l\),然后考虑 \([l,nxt_l-1]\) 这个区间,如果它的权值 \(v\) 大于 \([l+1,nxt_l-1]\) 的最大权不交区间集的权值 \(v'\),就令 \(\forall r\in[nxt_l-1,n]\),\([l,r]\) 的答案加上 \(v-v'\),这样查询相当于树状数组上一段前缀之和。\(O(n\log n)\) 维护即可。

const int MAXN=2e5;
int n,qu,p[MAXN+5],a[MAXN+5],b[MAXN+5],nxt[MAXN+5];
vector<tuple<int,int,int> >vec[MAXN+5];
void addqry(int l,int r,int id,int coef){vec[l].pb(mt(r,id,coef));}
ll res[MAXN+5],suma[MAXN+5],t[MAXN+5];
void add(int x,ll v){for(int i=x;i<=n;i+=(i&(-i)))t[i]+=v;}
ll query(int x){ll ret=0;for(int i=x;i;i&=(i-1))ret+=t[i];return ret;}
int main(){
	scanf("%d%d",&n,&qu);
	for(int i=1;i<=n;i++)scanf("%d",&p[i]);p[n+1]=n+1;
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),suma[i]=suma[i-1]+a[i];
	for(int i=1;i<=n;i++)scanf("%d",&b[i]);
	addqry(1,n,0,1);set<int>st;st.insert(1);st.insert(n+1);
	for(int i=1,x;i<=qu;i++){
		scanf("%d",&x);
		if(x!=1){
			if(st.find(x)!=st.end()){
				int pv=*(--st.lower_bound(x)),nt=*st.upper_bound(x);
				addqry(pv,nt-1,i,1);addqry(pv,x-1,i,-1);addqry(x,nt-1,i,-1);
				st.erase(st.find(x));
			}else{
				int pv=*(--st.lower_bound(x)),nt=*st.upper_bound(x);
				addqry(pv,nt-1,i,-1);addqry(pv,x-1,i,1);addqry(x,nt-1,i,1);
				st.insert(x);
			}
		}
	}
	static int stk[MAXN+5];int tp=0;
	for(int i=n+1;i;i--){
		while(tp&&p[stk[tp]]<p[i])--tp;
		nxt[i]=stk[tp];stk[++tp]=i;
	}
	for(int i=n;i;i--){
		ll v=suma[nxt[i]-1]-suma[i-1]-b[i],lst=query(nxt[i]-1);
		if(v>lst)add(nxt[i]-1,v-lst);
		for(auto t:vec[i])res[get<1>(t)]+=(suma[get<0>(t)]-suma[i-1]-query(get<0>(t)))*get<2>(t);
	}
	for(int i=1;i<=qu;i++)res[i]+=res[i-1];
	for(int i=1;i<=qu;i++)printf("%lld\n",res[i]);
	return 0;
}

标签:nxt,get,int,Codeforces,1495F,MAXN,vec,Squares,suma
From: https://www.cnblogs.com/tzcwk/p/Codeforces-1495F.html

相关文章

  • Codeforces Round 876 (Div. 2)
    PrefaceDP腐乳闪总出列!(本来以为大掉分的一把,但这个号因为挺新的所以竟然还能上挺多分的,压线完成了5场上紫)早知道去做E题了,感觉CF真得要看题目相性,有些题目就是一眼感觉不适合自己的说A.TheGoodArray一个要动点脑子的签到题,因为\(a_1,a_n\)必须等于\(1\),然后中间的\(n-1\)......
  • Codeforces Round 876 (Div. 2)题解
    CodeforcesRound876(Div.2)A.TheGoodArray标签greedymath题意对于任意\(i\in\{1,2,\dots,n\}\),要求数列\(a\)满足前\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\),后\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\)。思......
  • 2023.5 codeforces 杂题选做
    2023.5codeforces杂题选做E.Location\(n\le5\times10^4\)的范围,并且区间赋值、区间维护最值,可以考虑分块。然后对于散块的修改可以直接暴力,对于整块,由于\(b_i\)值不变,\(a_i\)值只有一个,思考如何快速求。由于\(\dfrac{\operatorname{lcm}(a_i,b_i)}{\gcd(a_i,b_i)}=\d......
  • Codeforces 1833E Round Dance
    看到shortestpaths来做的,但是好像没啥关系也没啥难度。首先能知道一个连通块肯定一次就能跳完,所以可以把连通块缩出来。然后有一个性质,记\(cz_i\)为\(i\)连通块内点种通过已知边推出的度数为\(1\)的个数为\(cz_i\),则\(cz_i\bmod2=0\)。记点\(i\)通过已知边推出......
  • codeforces Connected Components(寻找补图的连通块)
    http://codeforces.com/contest/920/problem/EE.ConnectedComponents?timelimitpertestmemorylimitpertestinputoutputn verticesand  edges.Insteadof......
  • Codeforces 1515I - Phoenix and Diamonds(值域倍增+线段树)
    首先\(c\)很大,因此复杂度跟\(c\)有关的项肯定只能是\(\logc\)之类的。类比IOI2021dungeons的套路,我们对值域进行分层,假设\(c\in[2^{\omega-1},2^{\omega})\),考虑令重量在\(\ge2^{\omega-1}\)的物品为“重物品”,其他物品为“轻物品”,那么一个显然的性质是我们最多只......
  • Codeforces Beta Round #2--B题 (DP)
    题目:Theleastroundway 1000*1000的方阵,每个格子有一个非负整数,现在要从左上走到右下,每次只能向下或者向右走。目标是使得所有走的格子里的数的乘积里,末尾0的个数最少,要求输出最有解和走法。不用怎么想也知道基本是个dp了,可以发现其实只有2和5的因子是有用的,但是如果状态同时记......
  • Codeforces Round 875 (Div. 2)B-D
    原题链接:https://codeforces.com/contest/1831原文:https://www.cnblogs.com/edgrass/p/17440602.html(B)Arraymerging主体思想是找到ab数组的最长相同字串(c中操作可实现连续)1#include<bits/stdc++.h>2usingnamespacestd;3intmain(){4intt;5cin>>......
  • Codeforces Round #548 (Div. 2) 题解
    题目链接http://codeforces.com/contest/1139 A.EvenSubstrings判断个位是否是奇数即可。#include<iostream>#include<set>#include<array>#include<vector>usingnamespacestd;typedeflonglongll;constintmx=1e5+10;lldp[mx][2];charstr[......
  • CodeForces 1250E [2-sat]
    题目链接:https://codeforces.com/contest/1250/problem/E 解题思路:首先根据反转的性质有:    有字符串a,b,a的反转A,b的反转B,如果a和b匹配值为K,那么A和B的值也为K    同样a和B匹配值为M,那么A和b的匹配值也为M,因此有对称性那么就可以转换成2-sat问题了,设点i的对立......