P6859 蝴蝶与花

Pro:

Sol:

有这样一个性质:一个1开头的1、2序列可以用区间和表示出1~s[n]的所有数字

#include<bits/stdc++.h>
#define N 2200000
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
#define ull unsigned long long
using namespace std;
inline int read()
{
	char ch=0;
	int x=0,flag=1;
	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();}
	return x*flag;
}
int tot,a[N];
struct Segment_Tree
{
	#define lson o<<1
	#define rson o<<1|1
	#define mid ((l+r)>>1)
	int f[N*4],sumv[N*4];
	inline void pushup(int o)
	{
		f[o]=f[lson]+f[rson];
		sumv[o]=sumv[lson]+sumv[rson];
	}
	int get(int o,int l,int r)
	{
		if(l==r)return l;
		if(f[lson])return get(lson,l,mid);
		else return get(rson,mid+1,r);
	}
	int solve(int o,int l,int r,int ql,int qr)
	{
		if(ql>qr)return 0;
		if(ql<=l&&r<=qr)return f[o]?get(o,l,r):0;
		int ans=0;
		if(ql<=mid)ans=solve(lson,l,mid,ql,qr);
		if(ans)return ans;
		if(qr>mid)ans=solve(rson,mid+1,r,ql,qr);
		return ans;
	}
	int query(int o,int l,int r,int s)
	{
		if(l==r){tot+=sumv[o];return l;}
		if(sumv[lson]>=s)return query(lson,l,mid,s);
		else{tot+=sumv[lson];return query(rson,mid+1,r,s-sumv[lson]);}
	}
	void optset(int o,int l,int r,int q,int k)
	{
		if(l==r){sumv[o]=k,f[o]=(k==1);return;}
		if(q<=mid)optset(lson,l,mid,q,k);
		else optset(rson,mid+1,r,q,k);
		pushup(o);		
	}
}T;
int main()
{
	int n=read(),qnum=read();
	for(int i=1;i<=n;i++)a[i]=read(),T.optset(1,1,n+1,i,a[i]);
	for(int i=1;i<=qnum;i++)
	{
		char ch[2];
		scanf("%s",ch);
		if(ch[0]=='A')
		{
			int s=read();tot=0;
			int x=T.query(1,1,n+1,s);
			if(s==0||tot<s){printf("none
");continue;}
			if(tot==s){printf("%d %d
",1,x);continue;}
			
			int l=1,r=x;
			int nl=T.solve(1,1,n+1,l,n);
			int nr=T.solve(1,1,n+1,r+1,n);
			if(!nl)nl=+inf;if(!nr)nr=+inf;
			if(nl==+inf&&nr==+inf){printf("none
");continue;}
			int len1=nl-l+1,len2=nr-r;
			if(len1<len2)l+=len1,r+=len1-1;
			if(len1==len2)l=nl+1,r=nr-1;
			if(len1>len2)l+=len2,r+=len2;
			if(r>n){printf("none
");continue;}
			printf("%d %d
",l,r);
		}
		else
		{
			int x=read(),k=read();
			a[x]=k;T.optset(1,1,n+1,x,k);
		}
	}
	return 0; 
} 
原文地址:https://www.cnblogs.com/Creed-qwq/p/13848015.html