首页 > 其他分享 >Codeforces 543E - Listening to Music(分块)

Codeforces 543E - Listening to Music(分块)

时间:2023-05-11 17:01:13浏览次数:34  
标签:SZ Listening int sum mn Codeforces Music BLK MAXN

根号 log 做法。能过 CF 的数据,但过不了校内模拟赛的数据/tuu

考虑从 \(f(i,x)\) 到 \(f(i+1,x)\) 的变化在哪里:少了个 \(a_i\) 多了个 \(a_{i+m}\),因此显然只有 \(x\) 在它俩中间才有 \(f(i,x)\ne f(i+1,x)\),即:

\[f(i+1,x)-f(i,x)=\begin{cases}-1&(a_i<x\le a_{i+m})\\1&(a_{i+m}<x\le a_i)\\0&\text{otherwise}\end{cases} \]

我们不妨记其为 \(g(i,x)\)。换句话说这个 \(g(i,x)\) 的贡献形式是一段区间。

而显然 \(f(j,x)=f(i,x)+\sum\limits_{k=i}^{j-1}g(k,x)\),因此询问等价于查询 \(f(l,x)\) 和 \(g(l,x),g(l+1,x),\cdots,g(r-1,x)\) 的最小前缀和。由于空间 64MB(一眼沙东 OI problemprovidercreep),考虑分块,对于前者直接将区间中的数排个序 lower_bound 即可,对于后者将这个块内所有区间左右端点当作关键点离散化,然后对每一段分别求出 \(x\) 在这一段内的最小前缀和和总和即可。块长取 \(\sqrt{n\log n}\) 时最优。

const int MAXN=2e5;
const int BLK_SZ=900;
const int BLK_CNT=MAXN/BLK_SZ;
int n,m,typ,a[MAXN+5],b[MAXN+5],L[MAXN+5],R[MAXN+5],blk_sz,blk_cnt,bel[MAXN+5];
int calc_less(int l,int r,int x){
	if(bel[l]==bel[r]){
		int sum=0;
		for(int i=l;i<=r;i++)sum+=(a[i]<x);
		return sum;
	}else{
		int sum=0;
		for(int i=l;i<=R[bel[l]];i++)sum+=(a[i]<x);
		for(int i=L[bel[r]];i<=r;i++)sum+=(a[i]<x);
		for(int i=bel[l]+1;i<bel[r];i++){
			int pos=lower_bound(b+L[i],b+R[i]+1,x)-b;
			sum+=pos-L[i];
		}return sum;
	}
}
tuple<int,int,int>c[MAXN+5];
int key[BLK_CNT+5][BLK_SZ*2+5],uni[BLK_CNT+5][BLK_SZ*2+5];
int cnt[BLK_SZ+5],num[BLK_SZ+5];
int sum[BLK_CNT+5][BLK_SZ*2+5],mn[BLK_CNT+5][BLK_SZ*2+5];
int calc_mn(int l,int r,int x){
	if(bel[l]==bel[r]){
		int _sum=0,_mn=0;
		for(int i=l;i<=r;i++){
			if(get<0>(c[i])<=x&&x<=get<1>(c[i]))_sum+=get<2>(c[i]);
			chkmin(_mn,_sum);
		}return _mn;
	}else{
		int _sum=0,_mn=0;
		for(int i=l;i<=R[bel[l]];i++){
			if(get<0>(c[i])<=x&&x<=get<1>(c[i]))_sum+=get<2>(c[i]);
			chkmin(_mn,_sum);
		}
		for(int i=bel[l]+1;i<bel[r];i++){
			int pos=upper_bound(uni[i]+1,uni[i]+num[i]+1,x)-uni[i]-1;
			chkmin(_mn,_sum+mn[i][pos]);_sum+=sum[i][pos];
		}
		for(int i=L[bel[r]];i<=r;i++){
			if(get<0>(c[i])<=x&&x<=get<1>(c[i]))_sum+=get<2>(c[i]);
			chkmin(_mn,_sum);
		}
		return _mn;
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
	blk_sz=BLK_SZ;blk_cnt=(n-1)/blk_sz+1;
	for(int i=1;i<=blk_cnt;i++){
		L[i]=(i-1)*blk_sz+1;R[i]=min(i*blk_sz,n);
		for(int j=L[i];j<=R[i];j++)bel[j]=i;
	}
	for(int i=1;i<=blk_cnt;i++)sort(b+L[i],b+R[i]+1);
	for(int i=1;i<=n-m;i++){
		if(a[i]<a[i+m])c[i]=mt(a[i]+1,a[i+m],-1);
		else if(a[i]>a[i+m])c[i]=mt(a[i+m]+1,a[i],1);
	}
	for(int i=1;i<=blk_cnt;i++){
		for(int j=L[i];j<=R[i];j++)if(get<2>(c[j]))
			key[i][++cnt[i]]=get<0>(c[j]),key[i][++cnt[i]]=get<1>(c[j])+1;
		key[i][++cnt[i]]=0;
		sort(key[i]+1,key[i]+cnt[i]+1);key[i][0]=-1;
		for(int j=1;j<=cnt[i];j++)if(key[i][j]!=key[i][j-1])uni[i][++num[i]]=key[i][j];
		for(int j=1;j<=num[i];j++){
			int SUM=0,MN=0;
			for(int k=L[i];k<=R[i];k++){
				if(get<0>(c[k])<=uni[i][j]&&uni[i][j]<=get<1>(c[k]))
					SUM+=get<2>(c[k]);
				chkmin(MN,SUM);
			}mn[i][j]=MN;sum[i][j]=SUM;
		}
	}
	int qu,lstans=0;scanf("%d",&qu);
	while(qu--){
		int l,r,x;scanf("%d%d%d",&l,&r,&x);x^=lstans;
		if(l==r)printf("%d\n",lstans=calc_less(l,l+m-1,x));
		else printf("%d\n",lstans=calc_less(l,l+m-1,x)+calc_mn(l,r-1,x));
	}
	return 0;
}

标签:SZ,Listening,int,sum,mn,Codeforces,Music,BLK,MAXN
From: https://www.cnblogs.com/tzcwk/p/Codeforces-543E.html

相关文章

  • # Codeforces Round 872 (Div. 2) 题解
    CodeforcesRound872(Div.2)题解A.LuoTianyiandthePalindromeString略B.LuoTianyiandtheTable略C.LuoTianyiandtheShow略D1.LuoTianyiandtheFloatingIslands(EasyVersion)题意在树上随机撒\(k(k\leq3)\)个关键点,规定一个点是好的当且仅当这个......
  • Codeforces Round 683 (Div. 1, by Meet IT) ABCDF题解
    F和D都在ABC上做过类似的,但是没打好,道心破碎。。。。A.Knapsack若物品质量在[(w+1)/2,w]之间做完了否则一直贪心加voidsolve(){intn;llw;cin>>n>>w;intc=n;for(inti=1;i<=n;i++){cin>>a[i];if(a[i]>w)c--;}if(!c){......
  • Codeforces [Hello 2020] 1284F New Year and Social Network(图论匹配推理+lct)
    https://codeforces.com/contest/1284/problem/F题目大意:有两个大小为n的树T1和T2.T2中的每条边(u,v)可以匹配T1中u到v路径上的所有边。求最大匹配,并给出方案。\(1<=n<=250000\)题解:首先你需要观察样例大胆猜想一定有完美匹配。考虑T1中的一个叶子x和它的父亲y。显然的是,从T2中随......
  • Codeforces F. Bits And Pieces(位运算)
    传送门.位运算的比较基本的题。考虑枚举\(i\),然后二进制位从大到小考虑,对于第\(w\)位,如果\(a[i][w]=1\),那么对\(j、k\)并没有什么限制。如果\(a[i][w]=0\),那么我们希望\((a[j]~and~a[k])[w]=1\),结合前面的限制,就是给定\(x\),问有没有\(x∈a[j]~and~a[k](i<j<k)\)。那么这应该是做一......
  • Codeforces Round 872 (Div. 2) A-D
    比赛地址A.LuoTianyiandthePalindromeString题意:给一个回文串,求最长的非回文子串的长度Solution判一下回文串是不是由相同的字母组成的,如果是的那么无解,如果不是答案就是len-1voidsolve(){ strings;cin>>s; intlen=s.length(); intsum=1; for(inti=1;i<s.leng......
  • Codeforces Round 872 (Div. 1 & Div. 2)
    这场寄大了。Mypredictorsay-101pts。https://codeforces.com/contest/1824https://codeforces.com/contest/18252A.LuoTianyiandthePalindromeString因为给出的\(s\)是一个回文串,所以答案只可能是\(-1\)或者\(n-1\),只需要看一下删掉哪一个即可,然后判定,这些都......
  • CodeForces - 631A Interview (思想)水
    TimeLimit: 1000MS MemoryLimit: 262144KB 64bitIOFormat: %I64d&%I64uCodeForces-631AInterviewSubmit StatusDescriptionBlakeisaCEOofalargecompanycalled"BlakeTechnologies".Heloveshiscompanyverymuchandhethinksthathi......
  • CodeForces - 630F Selection of Personnel (组合数学)
    TimeLimit: 500MS MemoryLimit: 65536KB 64bitIOFormat: %I64d&%I64uCodeForces-630FSelectionofPersonnelSubmit StatusDescriptionOnecompanyofITCitydecidedtocreateagroupofinnovativedevelopmentsconsistingfrom 5 to 7 peopleandhir......
  • CodeForces - 621B Wet Shark and Bishops (数学几何&技巧)
    TimeLimit: 2000MS MemoryLimit: 262144KB 64bitIOFormat: %I64d&%I64uCodeForces-621BWetSharkandBishopsSubmit StatusDescriptionToday,WetSharkisgiven n bishopsona 1000 by 1000 grid.Bothrowsandcolumnsofthegridarenumberedfro......
  • CodeForces - 618A Slime Combining (快速幂)
    CodeForces-618ASlimeCombiningTimeLimit: 2000MS MemoryLimit: 262144KB 64bitIOFormat: %I64d&%I64uSubmit StatusDescriptionYourfriendrecentlygaveyousomeslimesforyourbirthday.Youhave n slimesallinitiallywithvalue 1.Youare......