首页 > 其他分享 >[Ynoi2012] NOIP2015 充满了希望(扫描线+线段树)

[Ynoi2012] NOIP2015 充满了希望(扫描线+线段树)

时间:2023-08-03 21:44:11浏览次数:43  
标签:NOIP2015 int Ynoi2012 查询 扫描线 LL define

题目传送门

solution

简单题。

我们正着做扫描线。

设 \(t_i\) 表示位置 \(i\) 最后一次进行二操作的时间,那么一操作就是交换 \(t_x,t_y\) ,二操作就是区间复制。

对于三操作,开一个树状数组,如果查询的位置的 \(t_x=j\),就在 \(j\) 的位置上加一。

查询就是查询后缀和。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
int n,m,q;
int tag[N*4];
typedef long long LL;
LL C[N];
void upd(int x,LL v)
{
	for(int i=x;i;i-=i&-i)C[i]+=v; 
}
LL ask(int x)
{
	LL res=0;
	for(int i=x;i<=m;i+=i&-i)res+=C[i];
	return res;
}
void pushdown(int k)
{
	if(tag[k])
	{
		tag[k<<1]=tag[k];
		tag[k<<1|1]=tag[k];
		tag[k]=0;
	}
}
void cov(int k,int l,int r,int L,int R,int c)
{
	if(L<=l&&r<=R) 
	{
		tag[k]=c;
		return;
	}
	pushdown(k);
	int mid=(l+r)>>1;
	if(L<=mid)cov(k<<1,l,mid,L,R,c);
	if(R>mid) cov(k<<1|1,mid+1,r,L,R,c);
}
int get(int k,int l,int r,int x)
{
	if(l==r)return tag[k];
	pushdown(k);
	int mid=(l+r)>>1;
	if(x<=mid) return get(k<<1,l,mid,x);
	return get(k<<1|1,mid+1,r,x);
}
int a[N],b[N],c[N],d[N];
#define PII pair<int,int>
#define mk(x,y) make_pair(x,y)
#define X(x) x.first
#define Y(x) x.second
vector<PII> G[N];
LL Ans[N];
int main()
{
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&a[i],&b[i]);
		if(a[i]!=3)scanf("%d",&c[i]);
		if(a[i]==2)scanf("%d",&d[i]);
	}
	for(int i=1;i<=q;i++)
	{
		int l,r;
		scanf("%d %d",&l,&r);
		G[r].push_back(mk(l,i));
	}
	for(int i=1;i<=m;i++)
	{
		if(a[i]==1) 
		{
			int x=get(1,1,n,b[i]);
			int y=get(1,1,n,c[i]);
			cov(1,1,n,b[i],b[i],y);
			cov(1,1,n,c[i],c[i],x);
		}
		else if(a[i]==2) cov(1,1,n,b[i],c[i],i);
		else 
		{
			int c=get(1,1,n,b[i]);
			if(c) upd(c,d[c]);
		}
		for(auto U:G[i])Ans[U.second]=ask(U.first);
	}
	for(int i=1;i<=q;i++)printf("%lld\n",Ans[i]);
	return 0;
}

标签:NOIP2015,int,Ynoi2012,查询,扫描线,LL,define
From: https://www.cnblogs.com/jesoyizexry/p/17604564.html

相关文章

  • [Ynoi Easy Round 2021] TEST_152(颜色段数均摊+扫描线)
    题目传送门solution简单题,考虑正着做扫描线,维护最后一次覆盖每个位置的修改时间,这个可以用\(set\)维护颜色段数均摊。那么显然对于一个以当前位置为右端点的询问,其答案就是所有最后修改时间大于等于左端点的位置的数的和。开一个树状数组维护最后一次修改时间是\(i\)的位......
  • 【学习笔记】扫描线
    扫描线是用来求解图形面积并的一个算法。问题引入给定\(n\)个长方形,求它们的面积并。下面以两个长方形为例:对于这个问题,可以有容斥等做法,但是还有个更简单的方法——扫描线。扫描线扫描线,顾名思义,就是,拿一条“线”取扫(这里是从下往上扫,其实其它的扫的方式也是可以的):如图......
  • P2679 [NOIP2015 提高组] 子串 题解
    原题\(题目大意\)\(从字符串a中选出k个子串s_1,s_2,s_3...s_k使得s_1+s_2+s_3+...+s_k=b\)\(求总方案数对10^9+7取模的结果\)\(1\le|a|即n\le1000,1\le|b|即m\le200,1\lek\le|b|\)\(设f_{i,j,x}表示已经选到a的第i个字符,b的第j个字符,共选了x个子串的方案数\)\(则可得......
  • 【学习笔记】扫描线
    【别急,我也不会,没写完】目录定义:例题(解释):定义:如图:(图片来源:oiwiki)像这样的一条线在图上扫描时,便是扫描线。(呃呃和没说没有任何区别呢)因此可见扫面线往往是求矩形面积并集或周长并集的好工具,当然,也可以运用在二维图中。当然它不止可以从上往下扫,还可以从左往右扫:(当然自己......
  • 扫描线Manhattan Distance
    ProblemC.ManhattanDistance主要算法:扫描线二分来源:XIIISamaraRegionalIntercollegiateProgrammingContestRussia,Samara,March29,2020题意:给你二维平面上的n个点,每个点之间都存在一个曼哈顿距离,要求你求出第k小的曼哈顿距离\((2\leqn\leq100000)\)假如你......
  • 扫描线小复习
    扫描线目录扫描线思想实现思想扫描线的思想十分简单,就是把矩形分为多次小的矩形求解罢了,关键在于实现记得有一次周考就写挂了......实现首先想要正好不重不漏地扫过一个矩形(只有一个的情况下)而不影响其他非矩形地方的方法是什么?假设我扫描线是从下往上扫的,那么对于这个矩形......
  • 题解 [NOIP2015 提高组] 运输计划
    题目链接闲话:虽说是紫题,但慢慢想还是完全没有问题的。由于\(m\)个运输计划同时开始,所以耗费时间就是最慢的飞船耗费的时间(即最长时间)。考虑到题目让求最短时间,也就是最长的最短,可以二分。考虑二分最长时间(记作\(k\)),那么将所有路径分成两类,一类是原来耗费的时间就小于等于\(......
  • 扫描线 - 知识点梳理
    扫描线算法可解决平面内平行坐标轴的线段有关的问题,例如求平面上平行于坐标轴的矩形的面积并,其原理在于模拟一条扫描线从下往上扫描。线段树是一种灵活的LeafyTree,可以灵活地扫描线上统计线段的分布情况,将一部分信息储存在分支节点上,另一部分信息下传至叶子节点,因此线段树是扫描......
  • C++进制转换+扫描线算法(二维区间合并面积和)
    ......
  • [NOIP2015 提高组] 跳石头
    [NOIP2015提高组]跳石头题目背景一年一度的“跳石头”比赛又要开始了!题目描述这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有\(N\)块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从......