zoukankan      html  css  js  c++  java
  • P6859 蝴蝶与花

    链接

    显然从位置 (1) 开始,找到第一个大于等于 (s) 的位置 (pos),设 (val=sumlimits_{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
    ",pos);
    			else if(a[1]==1) printf("2 %d
    ",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
    ",p1-pos+2,p1+1);
    				else printf("%d %d
    ",p2+2,pos+p2);
    			}
    		}
    		else x=in(),y=in(),T.mdy(1,1,n,x,a[x]=y);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java static修饰符小记
    nginx的使用
    Java 日期时间格式化
    Java Annotation使用详解
    栈的应用-四则运算表达式
    计算机网络——学习笔记
    Python __builtin__模块
    搭建Harbor私有库
    Prometheus k8s方式安装
    Day4_字典循环
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/14335948.html
Copyright © 2011-2022 走看看