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

[NOIP2022] 比赛

时间:2023-05-28 21:33:15浏览次数:45  
标签:p1 比赛 rs int ll mid NOIP2022 ql

\(\mathcal Link\)

大半年前,我在没有难题的 NOIP 大败而归,以一个耻辱的分数。

注意到询问具有分治性。考虑类似线段树一样拆分询问,然后考虑跨过 \(\textit{mid}\) 的子区间贡献。

对于一个固定的 \(r\),考虑 \(l\) 的贡献。记 \(f\),\(g\) 分别代表 \(A\) 和 \(B\) 对应区间的最值。
考虑将其分成 4 类:

  • \(f(l)>f(r), g(l)>g(r)\),对应贡献为 \(f(l)g(l)\)
  • \(f(l)>f(r), g(l)\leq g(r)\),对应贡献为 \(f(l)g(r)\)
  • \(f(l)\leq f(r),g(l)>g(r)\),对应贡献为 \(f(r)g(l)\)
  • \(f(l)\leq f(r), g(l)\leq g(r)\),对应贡献为 \(f(r)g(r)\)

由于 \(f,g\) 都具有单调性且单调性相同,所以不会出现交叉,2,3 不会同时出现,然后会发现分布一定是 \(1\to 2/3\to 4\)。
考虑在扫描的时候动态维两个指针表示第一个非 1 的位置和第一个属于 4 的位置,并用线段树维护 \(ql=l,l+1,\cdots mid\) 时右端点的贡献和,查询时直接查询区间和即可。

注意为了保证复杂度,需要处理出分治树上每个节点对应的整区间的贡献,这是容易的。
总复杂度 \(\mathcal O(n\log^2 n)\)。

#include <bits/stdc++.h>
using namespace std;
using ll=unsigned long long;
#define pb push_back
namespace FastIO{
	char buf[1<<14], *p1=buf, *p2=buf;
	#define GetC() ((p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++)
	struct Ios{}io;
	template <typename _tp>
	Ios &operator >>(Ios &in, _tp &x){
		x=0; int w=0; char c=GetC();
		for(;!isdigit(c);w|=c=='-', c=GetC());
		for(;isdigit(c);x=x*10+(c^'0'), c=GetC());
		if(w) x=-x;
		return in;
	}
}
using FastIO::io;

const int N=2.5e5+5;
int n, m;
ll ans[N], a[N], b[N];
struct Quest{ int l, r, id; };
vector<Quest> v[N];

struct SegTree{
	ll sum[N<<2], tag[N<<2], fac[N<<2];
	ll init[N];
	#define ls(p) ((p)<<1)
	#define rs(p) ((p)<<1|1)
	void build(int p, int l, int r){
		tag[p]=sum[p]=0;
		if(l==r){
			fac[p]=init[l];
			return ;
		}
		int mid=(l+r)>>1;
		build(ls(p), l, mid);
		build(rs(p), mid+1, r);
		fac[p]=fac[ls(p)]+fac[rs(p)];
	}
	void whole(int p, ll k){
		sum[p]+=k*fac[p];
		tag[p]+=k;
	}
	void pushdown(int p){
		if(tag[p]){
			whole(ls(p), tag[p]);
			whole(rs(p), tag[p]);
			tag[p]=0;
		}
	}
	void pushup(int p){
		sum[p]=sum[ls(p)]+sum[rs(p)];
	}
	void modify(int p, int l, int r, int ql, int qr, ll k){
		if(ql<=l && r<=qr){
			whole(p, k);
			return ;
		}
		int mid=(l+r)>>1;
		pushdown(p);
		if(ql<=mid) modify(ls(p), l, mid, ql, qr, k);
		if(qr>mid) modify(rs(p), mid+1, r, ql, qr, k);
		pushup(p);
	}
	ll query(int p, int l, int r, int ql, int qr){
		if(ql<=l && r<=qr)
			return sum[p];
		int mid=(l+r)>>1;
		pushdown(p);
		if(qr<=mid) return query(ls(p), l, mid, ql, qr);
		if(ql>mid) return query(rs(p), mid+1, r, ql, qr);
		return query(ls(p), l, mid, ql, qr)+query(rs(p), mid+1, r, ql, qr);
	}
}T[4];

#define f(i) T[0].init[i] 
#define g(i) T[1].init[i]

ll solve(int l, int r){
	if(l==r){
		for(auto x:v[l])
			ans[x.id]+=a[l]*b[l];
		return a[l]*b[l];
	}
	int mid=(l+r)>>1;
	ll res=0;
	f(mid)=a[mid]; g(mid)=b[mid];
	for(int i=mid-1;i>=l;--i)
		f(i)=max(f(i+1), a[i]), g(i)=max(g(i+1), b[i]);
	f(mid+1)=a[mid+1]; g(mid+1)=b[mid+1];
	for(int i=mid+2;i<=r;++i)
		f(i)=max(f(i-1), a[i]), g(i)=max(g(i-1), b[i]);
	for(int i=l;i<=r;++i)
		T[2].init[i]=T[0].init[i]*T[1].init[i],
		T[3].init[i]=1;
	for(int i=0;i<=3;++i)
		T[i].build(1, l, mid);
	int p1=mid, p2=mid;
	for(int i=mid+1;i<=r;++i){
		while(p1>=l && !(f(p1)>f(i) && g(p1)>g(i))) --p1;
		while(p2>=l && f(p2)<=f(i) && g(p2)<=g(i)) --p2;
		if(p1>=l) T[2].modify(1, l, mid, l, p1, 1);
		if(p1!=p2){
			if(f(p1+1)>f(i) && g(p1+1)<=g(i)) T[0].modify(1, l, mid, p1+1, p2, g(i));
			else T[1].modify(1, l, mid, p1+1, p2, f(i));
		}
		if(p2!=mid) T[3].modify(1, l, mid, p2+1, mid, f(i)*g(i));
		for(auto x:v[i]){
			if(x.l>mid || (x.l==l && x.r==r)) continue;
			for(int type=0;type<4;++type)
				ans[x.id]+=T[type].query(1, l, mid, x.l, mid);
		}
		if(i==r){
			for(int type=0;type<4;++type)
				res+=T[type].query(1, l, mid, l, mid);
		}
	}
	vector<Quest> Tmp;
	{
		vector<Quest> Tmp2;
		for(auto x:v[r]){
			if(x.l==l) Tmp.pb(x);
			else Tmp2.pb(x);
		}
		swap(v[r], Tmp2);
	}
	for(int i=mid+1;i<=r;++i){
		for(auto &x:v[i]){
			if(x.l<=mid){
				v[mid].pb((Quest){ x.l, mid, x.id });
				x.l=mid+1;
			}
		}
	}
	res+=solve(l, mid);
	res+=solve(mid+1, r);
	for(auto x:Tmp){
		if(x.l==l)
			ans[x.id]+=res;
	}
	return res;
}

int main(){
	int Num; io>>Num>>n;
	for(int i=1;i<=n;++i) io>>a[i];
	for(int i=1;i<=n;++i) io>>b[i];
	io>>m;
	for(int i=1;i<=m;++i){
		int l, r; io>>l>>r;
		v[r].push_back((Quest){ l, r, i});
	}
	solve(1, n);
	for(int i=1;i<=m;++i)
		printf("%llu\n", ans[i]);
	return 0;
}

标签:p1,比赛,rs,int,ll,mid,NOIP2022,ql
From: https://www.cnblogs.com/pref-ctrl27/p/17438904.html

相关文章

  • 做题/比赛寄录
    2023.5.19T1+写成-,ans没初始化,100->0;T3M写成m,100->10。230->40。乐。2023.5.23哈希写丑了,而且puts("YES\n")。调了1小时,心态炸裂。2023.5.26T21l写成1,100->40。沦为暴力分。因为打羽毛球赢了而狂掉rp的屑xcy......
  • “百度杯”CTF比赛 2017 二月场——Web-爆破-3
    ==================================个人收获:1.php中MD5()计算数组会返回null如果用==0则为真 ==================================  题目:主要是代码审计,大家可以自己百度下都能看得懂的,这里我就直说关键的部分 关键部分代码在这if($_SESSION['whoami']==($value[0].$value[1......
  • “百度杯”CTF比赛 九月场 SQL-writeup
     这题自己的收获:用<>隔开敏感字符,绕过防注入 题目界面:刚开始还是老规矩输入and1=1 发现被拦截 此外测试了or发现也进行了拦截我们可以用下面的字符来替换and和orand---->&&  ,   or----->|| 替换后发现可以成功绕过接下来进行猜字段长度 发现orderby......
  • “百度杯”CTF比赛 九月场 类型:Web 题目名称:SQLi
    收获的知识:重定向一般发生在访问域名而且不加参数或者文件夹名,文件名这样的情况下sql注入也要留意HTTP信息的变化可以利用SQLmap跑一下看看有没有有用的信息不使用单引号和逗号的注入的注入技巧   发现页面空白然后查看源文件发现另一个页面进去后出现 后来手测和用sqlmap......
  • STI比赛任务一:【智能问答baseline】
    比赛简介百度搜索首届技术创新挑战赛:赛道一答案抽取STI比赛任务一:【比赛数据分析与长尾发现】STI比赛任务一:【NLP常见优化算法和上分Trick】STI比赛任务一:【智能问答baseline】任务定义本赛题任务是:给定一个用户搜索问题集合Q,基于每个搜索问题q,给定搜索引擎检索得到的网页文档集合......
  • java基于springboot+vue的篮球竞赛预约平台、比赛预约管理系统,附源码+数据库+lw文档+P
    1、项目介绍根据篮球竞赛预约平台的功能需求,进行系统设计。前台功能:用户进入系统可以实现首页,竞赛项目,平台公告,个人中心,后台管理等功能进行操作;后台由管理员和用户,主要功能包括首页,个人中心,用户管理,项目分类管理,竞赛项目管理,赛事预约管理,系统管理等功能;系统对这些功能进行整合......
  • NOIP2022游寄
    挂大分+考试失误(还是食力不够/kk)\(Day\)-\(114514\)至\(Day\)-\(1\)whk+口胡题目+Water(大部分时候都是Water)。\(Day0\)一整天都在疯狂打板子。图论打了\(5,6\)个,数据结构\(5,6\)个,数论\(10\)多个。网课关了摄像头就是水。晚上被很多\(dalao\)祝福,希望rp++。躺......
  • 有意思的比赛trick
    根号分治CF:https://codeforces.com/contest/1822/problem/G2//常用头文件!#include<bits/stdc++.h>usingnamespacestd;typedefint64_ti64;#defineINF0x3f3f3f3f//这个是int的最大值可直接赋值#definelINF0x3f3f3f3f3f3f3f//这个是longlong的最大值int......
  • 夺冠秘诀?华为软件精英挑战赛两届冠军这样复盘比赛经验
    摘要:作为两次获得全球总冠军的软挑老兵,刘露撰文分享其赛队参赛体验,包括解题思路及对抗策略、比赛收获等。本文分享自华为云社区《夺冠秘诀?华为软件精英挑战赛两届冠军这样复盘比赛经验》,作者:华为云社区精选。4月23日,2023第九届华为软件精英挑战赛-“普朗克计划”全球总决赛及颁......
  • 3651: 确定比赛名次
    描述 有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。  输入 输入有若......