P6859 蝴蝶与花

链接

显然从位置 \(1\) 开始,找到第一个大于等于 \(s\) 的位置 \(pos\),设 \(val=\sum\limits_{i=1}^{pos} a_i\)

\(val=s\) 直接输出即可,否则 \(a_{pos}\) 必然等于 \(2\),若 \(a_1=1\)\(l\) 向前移动一个即可。

找到从 \(1\)\(pos\) 开始的最后一个连续的 \(2\),显然在这一部分 \(l\) 移动一位 \(r\) 也要移动一位,因为权值之和都是 \(+2,-2\) 变化,我们和 \(s\) 相差 \(1\),在连续的 \(2\) 里面移动是不可能使 \(val=s\)
的。

僵局的打破是 \(1\) 的出现,只要 \(r\) 位置少加一个 \(1\) ,或 \(l\) 位置多减一个 \(1\) 就好了。无解的情况就是 \(r\)\(n\) \(a\) 都为 \(2\),且 \(r\) 的序列长度大于 \(l\) 的序列长度。

输出的方案最好自己用纸笔模拟一下。

代码用线段树实现。

#include<bits/stdc++.h>
#define IL inline
#define LL long long
using namespace std;
const int N=2e6+3;
int n,m,a[N];
IL int in(){
	char c;int f=1;
	while((c=getchar())<'0'||c>'9')
	  if(c=='-') f=-1;
	int x=c-'0';
	while((c=getchar())>='0'&&c<='9')
	  x=x*10+c-'0';
	return x*f;
}
struct segment{
	int Min[N<<2],sum[N<<2];
	#define ls k<<1
	#define rs k<<1|1
	IL void pushup(int k){Min[k]=min(Min[ls],Min[rs]),sum[k]=sum[ls]+sum[rs];}
	void build(int k,int l,int r){
		if(l==r){Min[k]=sum[k]=a[l];return;}
		int mid=l+r>>1;
		build(ls,l,mid),build(rs,mid+1,r);
		pushup(k);
	}
	int query(int k,int l,int r,int ll,int rr){
		if(l>=ll&&r<=rr) return sum[k];
		int mid=l+r>>1;
		if(rr<=mid) return query(ls,l,mid,ll,rr);
		if(ll>mid) return query(rs,mid+1,r,ll,rr);
		return query(ls,l,mid,ll,rr)+query(rs,mid+1,r,ll,rr);
	}
	void mdy(int k,int l,int r,int u,int v){
		if(l==r){Min[k]=sum[k]=v;return;}
		int mid=l+r>>1;
		if(u<=mid) mdy(ls,l,mid,u,v);
		else mdy(rs,mid+1,r,u,v);
		pushup(k);
	}
	int ask1(int k,int l,int r,int s){
		if(l==r) return l;
		int mid=l+r>>1;
		if(sum[ls]>=s) return ask1(ls,l,mid,s);
		return ask1(rs,mid+1,r,s-sum[ls]);
	}
	int ask2(int k,int l,int r,int p){
		if(l>=p&&Min[k]==2) return 0;
		if(l==r) return l;
		int mid=l+r>>1;
		if(p>mid) return ask2(rs,mid+1,r,p);
		int pos=ask2(ls,l,mid,p);
		if(pos) return pos;
		return ask2(rs,mid+1,r,p);
	}
}T;
int main()
{
	char op[10];int x,y,z;
	n=in(),m=in();
	for(int i=1;i<=n;++i) a[i]=in();
	T.build(1,1,n);
	while(m--){
		scanf("%s",op+1);
		if(op[1]=='A'){
			if(!(x=in())){puts("none");continue;};
			int pos=T.ask1(1,1,n,x),val=T.query(1,1,n,1,pos);
			if(val<x) puts("none");
			else if(val==x) printf("1 %d\n",pos);
			else if(a[1]==1) printf("2 %d\n",pos);
			else{
				int p1=T.ask2(1,1,n,pos),p2=T.ask2(1,1,n,1);
				if(!p1) p1=n;else --p1;
				if(!p2) p2=n;else --p2;
				if(p1==n&&p1-pos+1<=p2) puts("none");
				else if(p1-pos+1<=p2) printf("%d %d\n",p1-pos+2,p1+1);
				else printf("%d %d\n",p2+2,pos+p2);
			}
		}
		else x=in(),y=in(),T.mdy(1,1,n,x,a[x]=y);
	}
	return 0;
}
posted @ 2021-01-27 17:16  (o-ωq)).oO  阅读(153)  评论(0编辑  收藏  举报