首页 > 其他分享 >P8868 [NOIP2022] 比赛

P8868 [NOIP2022] 比赛

时间:2023-09-15 10:50:07浏览次数:51  
标签:cur val cl int rs tag NOIP2022 P8868 比赛

https://www.luogu.com.cn/problem/P8868

我学会了历史和!

在一阵扫描线过后,你会发现,\([l,r]\) 的所有子区间的答案,就一定是扫到 \(i\) 的时候,加上 \([k,i]\) 的答案,\(k\le i,i\in[l,r]\),然后又因为只有当 \(i\ge l\) 的时候,才能对左端点在 \([l,r]\) 的答案贡献,因此,你会发现这个东西就是一个扫过去,然后区间加法,然后查询区间历史和的问题。

即对于 \([l,r]\),我们需要知道 \([l',r']\subset[l,r]\) 的答案,那么我们可以扫描线,扫到 \(i\) 的时候,用序列的第 \(j\) 位表示 \([j,i]\) 的答案。因为 \(i\) 只会更新 \(j\le i\),因此当扫到 \(i<l\) 的时候,对答案无影响。当 \(i\ge l\) 的时候,会更新左端点的答案,此时若左端点在范围内,显然是要贡献给答案的,注意到,左端点的限制是仅跟查询的区间有关的,而对于一个询问 \([l,r]\) 我们可以把它挂在 \(r\) 上,那么需要往后一位扫,更新,贡献,往后一位扫,更新,贡献……这样的一个过程,对于贡献抽离出来,发现就是历史和问题。

总结一下,对于抽象到二维平面问题的矩形和,我们可以利用扫描线,然后维护更新操作,那么答案一定某些左端点的历史答案的和,这些左端点仅跟询问的区间有关

具体一下就是 \([l,r]\) 的子区间有啥呢?

\([l,l]\)

\([l,l+1],[l+1,l+1]\)

\([l,l+2],[l+1,l+2],[l+2,l+2]\)

...
\([l,r],[l+1,r],[l+2,r]...[r-1,r],[r,r]\)

如果说扫到某个位置,比如 \(l+2\),那么比如说 \([l,l+2]\) 的答案是贡献到 \(l\) 上的。

那么对于 \([l,l],[l,l+1],[l,l+2],...,[l,r]\) 这些,你会发现就是扫到 \(r\) 后 \(l\) 的历史和。

嗯!

然后历史和,就是在每次更新后,将当前的答案,贡献给历史和,你就把矩阵乘法的形式写一写,然后嗯算哪些位置可能非零,然后抽离出来大力算。

然后在维护的时候不要想一步到位,抽离出来每一个步骤比较好做。比如你要时刻维护历史和,那你可以看成更新完,然后再来一个维护历史和的操作,而不是在更新的过程中就顺带维护了历史和。

更新后必须的更新历史和。

\([Ans,val,S_a,S_b,len]\to[Ans+val,val,S_a,S_b,len]\)

更新 \(A\)。

\([Ans,val,S_a,S_b,len]\to[Ans,v\cdot S_b,v\cdot len,S_b,len]\)

更新 \(B\) 同理。

#include <bits/stdc++.h>
//#define int long long
#define ull unsigned long long
#define ls ((cur)<<1)
#define rs ((ls)|1)
#define pb push_back
using namespace std;
const int N=(int)(2.5e5+5);
vector<pair<int,int> >vec[N];
ull ans[N];
int La[N],Lb[N],tp,st[N],n,q,a[N],b[N];

struct Matt {
	ull a[5];
	Matt() {
		memset(a,0,sizeof(a));
	}
	void clr() {
		memset(a,0,sizeof(a));
	}
}val[N<<2];

struct Mat {
	ull a[14];
	Mat() {
		memset(a,0,sizeof(a));
	}
	void clr() {
		memset(a,0,sizeof(a));
	}
	void clr1() {
		clr();
		a[0]=a[2]=a[5]=a[8]=a[13]=1;
	}
}tag[N<<2],P;

Matt Mul(const Matt &f,const Mat &g) {
	Matt res;
	res.a[0]=1llu*f.a[0]*g.a[0]+1llu*f.a[1]*g.a[1]+1llu*f.a[2]*g.a[3]+1llu*f.a[3]*g.a[6]+1llu*f.a[4]*g.a[9];
	res.a[1]=1llu*f.a[1]*g.a[2]+1llu*f.a[2]*g.a[4]+1llu*f.a[3]*g.a[7]+1llu*f.a[4]*g.a[10];
	res.a[2]=1llu*f.a[2]*g.a[5]+1llu*f.a[4]*g.a[11];
	res.a[3]=1llu*f.a[3]*g.a[8]+1llu*f.a[4]*g.a[12];
	res.a[4]=1llu*f.a[4]*g.a[13];
	return res;
} 

Mat mul(const Mat &f,const Mat &g) {
	Mat res;
	res.a[0]=1llu*f.a[0]*g.a[0];
	res.a[1]=1llu*f.a[1]*g.a[0]+1llu*f.a[2]*g.a[1];
	res.a[2]=1llu*f.a[2]*g.a[2];
	res.a[3]=1llu*f.a[3]*g.a[0]+1llu*f.a[4]*g.a[1]+1llu*f.a[5]*g.a[3];
	res.a[4]=1llu*f.a[4]*g.a[2]+1llu*f.a[5]*g.a[4];
	res.a[5]=1llu*f.a[5]*g.a[5];
	res.a[6]=1llu*f.a[6]*g.a[0]+1llu*f.a[7]*g.a[1]+1llu*f.a[8]*g.a[6];
	res.a[7]=1llu*f.a[7]*g.a[2]+1llu*f.a[8]*g.a[7];
	res.a[8]=1llu*f.a[8]*g.a[8];
	res.a[9]=1llu*f.a[9]*g.a[0]+1llu*f.a[10]*g.a[1]+1llu*f.a[11]*g.a[3]+1llu*f.a[12]*g.a[6]+1llu*f.a[13]*g.a[9];
	res.a[10]=1llu*f.a[10]*g.a[2]+1llu*f.a[11]*g.a[4]+1llu*f.a[12]*g.a[7]+1llu*f.a[13]*g.a[10];
	res.a[11]=1llu*f.a[11]*g.a[5]+1llu*f.a[13]*g.a[11];
	res.a[12]=1llu*f.a[12]*g.a[8]+1llu*f.a[13]*g.a[12];
	res.a[13]=1llu*f.a[13]*g.a[13];
	return res;
}

void push_up(int cur) {
	val[cur].a[0]=val[ls].a[0]+val[rs].a[0];
	val[cur].a[1]=val[ls].a[1]+val[rs].a[1];
	val[cur].a[2]=val[ls].a[2]+val[rs].a[2];
	val[cur].a[3]=val[ls].a[3]+val[rs].a[3];
	val[cur].a[4]=val[ls].a[4]+val[rs].a[4];
}

void build(int cur,int l,int r) {
	val[cur].clr(); tag[cur].clr1();
	val[cur].a[4]=r-l+1;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(ls,l,mid); build(rs,mid+1,r);
	push_up(cur);
}

void push_down(int cur) {
	tag[ls]=mul(tag[ls],tag[cur]);
	tag[rs]=mul(tag[rs],tag[cur]);
	val[ls]=Mul(val[ls],tag[cur]);
	val[rs]=Mul(val[rs],tag[cur]);
	tag[cur].clr1();
}

void upt(int cur,int l,int r,int cl,int cr) {
	if(cl<=l&&r<=cr) {
		val[cur]=Mul(val[cur],P);
		tag[cur]=mul(tag[cur],P);
		return ;
	}
	int mid=(l+r)>>1;
	push_down(cur);
	if(cl<=mid) upt(ls,l,mid,cl,cr);
	if(cr>mid) upt(rs,mid+1,r,cl,cr);
	push_up(cur);
}

ull qry(int cur,int l,int r,int cl,int cr) {
	if(cl<=l&&r<=cr) {
		return val[cur].a[0];
	}
	int mid=(l+r)>>1;
	push_down(cur);
	if(cr<=mid) return qry(ls,l,mid,cl,cr);
	if(cl>mid) return qry(rs,mid+1,r,cl,cr);
	return qry(ls,l,mid,cl,cr)+qry(rs,mid+1,r,cl,cr);
}

signed main() {
// 	freopen("match.in","r",stdin);
// 	freopen("match.out","w",stdout);
	cin.tie(0); ios::sync_with_stdio(false);
	cin>>n; cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	for(int i=1;i<=n;i++) {
		while(tp&&a[st[tp]]<a[i]) {
			--tp;
		}
		if(tp) La[i]=st[tp];
		st[++tp]=i;
	}
	tp=0;
	for(int i=1;i<=n;i++) {
		while(tp&&b[st[tp]]<b[i]) {
			--tp;
		}
		if(tp) Lb[i]=st[tp];
		st[++tp]=i;
	}
	
	cin>>q;
	for(int i=1;i<=q;i++) {
		int l,r; cin>>l>>r;
		vec[r].pb(make_pair(l,i));
	}
	build(1,1,n);
	for(int i=1;i<=n;i++) {
		P.clr();
		P.a[0]=1; P.a[7]=a[i]; P.a[8]=1; P.a[11]=a[i]; P.a[13]=1;
		upt(1,1,n,La[i]+1,i);
		P.clr();
		P.a[0]=1; P.a[4]=b[i]; P.a[5]=1; P.a[12]=b[i]; P.a[13]=1;
		upt(1,1,n,Lb[i]+1,i);
		P.clr1(); P.a[1]=1;
		upt(1,1,n,1,i);
		for(auto x:vec[i]) ans[x.second]+=qry(1,1,n,x.first,i); 
	}
	for(int i=1;i<=q;i++) cout<<ans[i]<<'\n';
	return 0;
} 

标签:cur,val,cl,int,rs,tag,NOIP2022,P8868,比赛
From: https://www.cnblogs.com/xugangfan/p/17704310.html

相关文章

  • 暑假集训Day19 比赛题解
    2023-08-0516:22:13总结这次打下来,由于T2贪心不够完全,T3模拟\(5\)个时不是最优,T4想到暴力做法但是来不及打,加之全都是捆绑测试点,导致我T2,T3虽然加起来有不少点对了,但是还是判全错,最后也只剩下T1的100。感觉这次前三题也不难,都是可做的,T4的30pts暴力也很白给,但......
  • 通过凯利指数——分析足球比赛的胜平负
    ......
  • 《动手学深度学习 Pytorch版》 4.10 实战Kaggle比赛:预测比赛
    4.10.1下载和缓存数据集importhashlibimportosimporttarfileimportzipfileimportrequests#@saveDATA_HUB=dict()DATA_URL='http://d2l-data.s3-accelerate.amazonaws.com/'defdownload(name,cache_dir=os.path.join('..','data'......
  • 【题解】NOIP2022
    怎么看T3也不是那么难,可是为啥赛时就是被卡死了[难过]不补\(B\)题了,ad-hoc。A.种花题目描述:小C决定在他的花园里种出\(\texttt{CCF}\)字样的图案,因此他想知道\(\textttC\)和\(\textttF\)两个字母各自有多少种种花的方案;不幸的是,花园中有一些土坑,这些位置无法种......
  • Intel One API黑客松比赛 ———Unet尝试图像分割
    感谢Intel提供这一次机会,我能够很幸运的参与进来,并且提高自己的编程技术。在这次比赛的题目是:预期解决方案::1.使用英特尔®AI分析工具套件中的适当组件开发一个深度学习模型,用于准确、快速检测并对道路上的对象进行分割。:2.使用包括挑战赛指定的真实场景(如各种天气条件、光线条......
  • 荣耀比赛如何报名
    点击链接https://cloud.51cto.com/act/honor/Talents2023然后找到下面的按钮,点击进入来到这个页面然后会跳转到官网报名:https://developer.hihonor.com/cn/tg/page/tg2023031504156474?source=kfzds_wbqd2点击立即报名输入账号密码然后完成开发者认证。私发我电话和姓名。然后低码......
  • 比赛 VP 记录
    前言我是傻逼,天天被大佬们吊锤。能不咕咕咕就不错了!\(\text{NOI2023Day2}\)得分:\(111/300\)A赛时得分\(75'\)。难得有我会的D2T1(好吧其实去年的D2T1也很容易得\(80+\)的高分)。这题我想了将近两个小时思路才呼之欲出,写完之后又调了一个多小时,才过了大样例。上界开......
  • 20230823比赛
    T1MyCowAteMyHomeworkGMOJ6659DescriptionInyourbovinehistoryclass,youhavebeengivenaratherlonghomeworkassignmentwithNquestions(3≤N≤100,000),eachgradedwithanintegerscoreintherange0...10,000.Asisoftencustomary,yourtea......
  • 牛客七夕比赛 题解
    标准的算法竞赛题有下面几个,写这篇博客主要是这个M很有意思,一直没绕过来这个弯如果你有更牛逼的构造方法欢迎交流指导。B构造边长为\(n\)的矩阵,使得每个\(2\times2\)的子矩形的权值和的极差最小两个指针L=1,R=\(n^2\)。将网格黑白染色后按照顺序遍历,黑色填\(R\)......
  • 20230822比赛
    T1CowPoetryDescription不为FarmerJohn所知的是,Bessie还热衷于资助艺术创作!最近,她开始研究许多伟大的诗人们,而现在,她想要尝试创作一些属于自己的诗歌了。Bessie认识N(1≤N≤5000)个单词,她想要将她们写进她的诗。Bessie已经计算了她认识的每个单词的长度,以音节为单位,并且她将......