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\n");continue;}
if(tot==s){printf("%d %d\n",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\n");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\n");continue;}
printf("%d %d\n",l,r);
}
else
{
int x=read(),k=read();
a[x]=k;T.optset(1,1,n+1,x,k);
}
}
return 0;
}