luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分)

luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分)

Luogu

题外话1:

LN四个人切D1T2却只有三个人切D1T1

很神必

我是傻逼。

题外话2:

1e6的数据直接io?

这野蛮至极你知道吗。

出题人这是要向全国人民谢罪的。

题解时间

70pts:

求最大的 $ min(presum0[i],sufsum1[i]) $ 。

一个前缀和,一个后缀和。

二分+树状数组可以找到答案。

对于输出最大温度,再二分一次。

$ O( n log ^ {2} n ) $ 。

100pts:

上面两个都改成直接线段树上二分就是一个 $ log $ 。

离散化一下减少常数便于操作。

详情看代码。

虽然洛谷上卡而且考试时没有O2,但是你要相信吸吸艾富用无数选手缴纳的费用购置的8700k的力量(

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long lint;
template<typename TP>inline void read(TP &tar)
{
	TP ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
	tar=ret*f;
}
namespace RKK
{
const int N=2000011;
struct ques{int t,s,x,v;}q[N];
int lst[N<<1],n;
int qaq;
int find1(int x)
{
	int l=1,r=n,m;
	while(l<=r)
	{
		m=l+r>>1;
		if(lst[m]==x) return m;
		else if(lst[m]<x) l=m+1;
		else r=m-1;
	}
}
int find0(int x)
{
	int ret=n+1,l=1,r=n,m;
	while(l<=r)
	{
		m=l+r>>1;
		if(lst[m]>=x) ret=m,r=m-1;
		else l=m+1;
	}
	return ret;
}
int v[N<<2][2];
void edit(int s,int w,int x,int px=1,int pl=0,int pr=n)
{
	if(pl==pr){v[px][s]+=w;return;}
	int pm=pl+pr>>1;
	if(x<=pm) edit(s,w,x,px<<1,pl,pm);
	else edit(s,w,x,px<<1|1,pm+1,pr);
	v[px][s]=v[px<<1][s]+v[px<<1|1][s];
}
int sa[2],ans,ansi,p[2];
void getans(int px=1,int pl=0,int pr=n)
{
	if(pl==pr) return;
	int pm=pl+pr>>1;
	p[0]=sa[0]+v[px<<1][0],p[1]=sa[1]+v[px<<1|1][1];
	int tmp=min(p[0],p[1]);
	if(tmp>ans) ans=tmp,ansi=pm+1;
	if(p[0]<p[1]) sa[0]+=v[px<<1][0],getans(px<<1|1,pm+1,pr);
	else if(p[0]>p[1]) sa[1]+=v[px<<1|1][1],getans(px<<1,pl,pm);
	else return;
}
void query(int px=1,int pl=0,int pr=n)
{
	if(pl==pr) return;
	int pm=pl+pr>>1;
	if(pm+1<=ansi) sa[0]+=v[px<<1][0],query(px<<1|1,pm+1,pr);
	else
	{
		p[0]=sa[0]+v[px<<1][0],p[1]=sa[1]+v[px<<1|1][1];
		int tmp=min(p[0],p[1]);
		if(tmp==ans)
		{
			ansi=pm+1;
			sa[0]+=v[px<<1][0],query(px<<1|1,pm+1,pr);
		}else sa[1]+=v[px<<1|1][1],query(px<<1,pl,pm);
	}
}


int main()
{
	read(qaq);for(int i=1;i<=qaq;i++)
	{
		read(q[i].t),read(q[i].s);
		if(q[i].t==1)
		{
			read(q[i].x),read(q[i].v);
			if(q[i].s==1) lst[++n]=q[i].x;
		}
	}
	sort(lst+1,lst+1+n),n=unique(lst+1,lst+1+n)-(lst+1);
	int ans1=0,ans2=0;
	for(int i=1;i<=qaq;i++)
	{
		if(q[i].t==1)
		{
			if(q[i].s==1) q[i].x=find1(q[i].x),edit(1,q[i].v,q[i].x);
			else q[i].x=find0(q[i].x),edit(0,q[i].v,q[i].x-1);
		}else
		{
			int j=q[i].s;
			if(q[j].s==1) edit(1,-q[j].v,q[j].x);
			else edit(0,-q[j].v,q[j].x-1);
		}
		sa[0]=sa[1]=0,ansi=ans=0;
		getans();
		sa[0]=sa[1]=0;;
		if(ans) query();
		if(ans==0) puts("Peace");
		else printf("%d %d\n",lst[ansi],ans*2);
	}
	return 0;
}
}
int main(){return RKK::main();}
posted @ 2020-06-23 17:10  RikukiIX  阅读(255)  评论(0编辑  收藏  举报