专栏文章

题解:P11896 「LAOI-9」此方的座位

P11896题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mipqyva1
此快照首次捕获于
2025/12/03 16:30
3 个月前
此快照最后确认于
2025/12/03 16:30
3 个月前
查看原文

前置知识:

本题思路

显然发出的噪音就是两段线段。
首先考虑没有降噪设备的时候怎么做。
发现其实就是李超线段树板子题(甚至只有没有精度差)。
加上降噪设备之后,每段线段就会再次“分裂”(就像光的折射一样),变成两条线段。
仍然是板子题。
降噪设备用 setset 维护即可。
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
bool Beginning;

#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define se second
#define fi first
using PII=pair<int,int>;
using PIB=pair<int,bool>;
using PBI=pair<bool,int>;
using PBB=pair<bool,bool>;
using PDI=pair<double,int>;
using PID=pair<int,double>;

namespace Memory_Love{
	int read(){ int x=0; bool flag=1; char ch=getchar();
		while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();}
		while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return flag? x:-x;}
	template<typename T> void read(T &x){ bool flag=1; x=0; char ch=getchar();
		while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();}
		while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} x=(flag? x:-x);}
	template<typename T,typename ...Args> void read(T &Re,Args &...Res){read(Re),read(Res...);}
	template<typename T> void write(T x,char ch=0){if(x<0) x=-x,putchar('-');
		static short s[35],top=-1; do{s[++top]=x%10;x/=10;}while(x);
		while(~top) putchar(s[top--]+48); if(ch) putchar(ch);}
	int gcd(int a,int b){return b==0? a:gcd(b,a%b);}
	int lcm(int a,int b){return a/gcd(a,b)*b;}
	int lowbit(int x){return (x&-x);}
} using namespace Memory_Love;
const int N=1e5+5;
const int INF=0x3f3f3f3f3f3f3f3fll;
int n,m,a[N];
set<int> S;

#define Tree(u) tree[u]
#define Point(u) LINE[u]
#define F(u,x) Point(u).f(x)
#define lson(u) (u<<1)
#define rson(u) (u<<1|1)
#define mid (left+right>>1) 
struct Line
{
	int k,b;
	Line(int K=0,int B=0){k=K,b=B;}
	int f(int x){return k*x+b;}
	bool friend operator !=(const Line &a,const Line &b){return a.k!=b.k || a.b!=b.b;}
};
struct Segment_Tree
{
	Line LINE[N<<2];
	int tree[N<<2],tot;
	Line New_Line(double k,double b){return Line(k,b);}
	bool comp(int x,int y,int pos){return F(x,pos)>F(y,pos);}
	PII Max(PII a,PII b){return a.fi>b.fi? a:b;}
	void addtag(int u,int left,int right,int x)
	{
		int &y=Tree(u);
		if(comp(x,y,mid)) swap(x,y);
		if(comp(x,y,left)) addtag(lson(u),left,mid,x);
		if(comp(x,y,right)) addtag(rson(u),mid+1,right,x);
	}
	void update(int u,int L,int R,int x,int left=1,int right=n)
	{
		if(L<=left && R>=right)
		return addtag(u,left,right,x);
		if(L<=mid) update(lson(u),L,R,x,left,mid);
		if(R>mid)  update(rson(u),L,R,x,mid+1,right);
	}
	void insert_Pre(int x,int xx,int yy,double k)
	{
		int b=yy-k*xx;
		Point(++tot)=New_Line(k,b);
		return update(1,x,xx,tot);
	}
	void insert_Nex(int x,int y,int xx,double k)
	{
		int b=y-k*x;
		Point(++tot)=New_Line(k,b);
		return update(1,x,xx,tot);
	}
	PII query(int u,int x,int left=1,int right=n)
	{
		if(left==right)
		return mp(F(Tree(u),x),Tree(u));
		PDI ans=mp(F(Tree(u),x),Tree(u));
		if(x<=mid) ans=Max(ans,query(lson(u),x,left,mid));
		else ans=Max(ans,query(rson(u),x,mid+1,right));
		return ans;
	}
}ST;

void solve(int x,int y)
{
	if(S.find(x)!=S.end()) S.erase(x);
	
	int Pre=(*--S.lower_bound(x));
	int Nex=(*S.upper_bound(x));
	
	if(Pre==-INF)
	ST.insert_Pre(1,x,y,a[x]);
	else
	{
		ST.insert_Pre(Pre,x,y,a[x]);
		ST.insert_Pre(1,Pre,y-a[x]*(x-Pre),a[x]*2);
	}
	
	if(Nex==INF)
	ST.insert_Nex(x,y,n,-a[x]);
	else
	{
		ST.insert_Nex(x,y,Nex,-a[x]);
		ST.insert_Nex(Nex,y-a[x]*(Nex-x),n,-a[x]*2);
	}
}

bool Ending;
signed main()
{
	int i,kind,x,y,last_ans=0;
	read(n,m);
	S.insert(-INF),S.insert(INF);
	for(i=1;i<=n;i++) a[i]=read();
	for(i=1;i<=n;i++)
	{
		x=read();
		if(x) S.insert(i);
	}
	while(m--)
	{
		read(kind,x);
		x=(x+last_ans-1)%n+1;
		if(kind==1)
		{
			y=read();
			solve(x,y);
		}
		if(kind==2) write(last_ans=max(ST.query(1,x).fi,0ll),'\n');
		if(kind==3) S.insert(x);
	}
	
	cerr<<"\nused:"<<(abs(&Ending-&Beginning)/1048576)<<"MB\n";
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...