• CF1217E Sum Queries? (线段树)


    完了,前几天才说 edu 的 DEF 都不会,现在打脸了吧 qwq

    其实在刚说完这句话 1min 就会了 D,3min 就会了 E

    发现,对于大小 (ge 3) 的不平衡集合,它至少有一个大小为 (2) 的子集是不平衡的。

    证明,发现对于大小为 (2) 的集合,平衡当且仅当两数的数位交为空(对于任意一位,至多一个数在这一位上不是 (0))。

    反证一波,如果大集合没有大小为 (2) 的不平衡集合,那么任意两数的数位交都为空,那么大集合也是平衡的,矛盾了。

    所以,只需要考虑大小为 (2) 的集合。

    这个就能线段树简单做了,每个线段树维护 (ans) 表示这个区间中的答案,(mn_i) 表示这个区间中第 (i) 位有值的数的最小值。pushup 具体看代码。

    时间复杂度 (O((n+qlog n)log a_i))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=200020,pw[9]={1,10,100,1000,10000,100000,1000000,10000000,100000000};
    #define MP make_pair
    #define PB push_back
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline ll read(){
    	char ch=getchar();ll x=0,f=0;
    	while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f?-x:x;
    }
    int n,m,a[maxn];
    struct node{
    	ll ans,mn[9];
    	node operator+(const node &nd)const{
    		node s;
    		s.ans=min(ans,nd.ans);
    		FOR(i,0,8) s.ans=min(s.ans,mn[i]+nd.mn[i]),s.mn[i]=min(mn[i],nd.mn[i]);
    		return s;
    	}
    }seg[maxn*4];
    inline int get(int x,int id){return x/pw[id]%10;}
    void build(int o,int l,int r){
    	if(l==r){
    		seg[o].ans=1e18;
    		FOR(i,0,8) seg[o].mn[i]=get(a[l],i)?a[l]:1e18;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(lson);build(rson);
    	seg[o]=seg[o<<1]+seg[o<<1|1];
    }
    void update(int o,int l,int r,int p,int v){
    	if(l==r){
    		seg[o].ans=1e18;
    		FOR(i,0,8) seg[o].mn[i]=get(v,i)?v:1e18;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(mid>=p) update(lson,p,v);
    	else update(rson,p,v);
    	seg[o]=seg[o<<1]+seg[o<<1|1];
    }
    node query(int o,int l,int r,int ql,int qr){
    	if(l>=ql && r<=qr) return seg[o];
    	int mid=(l+r)>>1;
    	if(mid<ql) return query(rson,ql,qr);
    	if(mid>=qr) return query(lson,ql,qr);
    	return query(lson,ql,qr)+query(rson,ql,qr);
    }
    int main(){
    	n=read();m=read();
    	FOR(i,1,n) a[i]=read();
    	build(1,1,n);
    	while(m--){
    		int op=read(),x=read(),y=read();
    		if(op==1) update(1,1,n,x,y);
    		else{
    			ll ans=query(1,1,n,x,y).ans;
    			printf("%lld
    ",ans>=2e9?-1ll:ans);
    		}
    	}
    }
    
  • 相关阅读:
    退役 AFO
    object_id()函数
    DataRow数组根据指定列排序
    窗口函数详解
    窗口函数详细用法
    聚合函数count里面加条件
    C#全局钩子和局部钩子记录
    SqlServer日期时间函数
    SQL中字符串截取、连接、替换等函数的用法
    C# 字符串多行显示、文本换行
  • 原文地址:https://www.cnblogs.com/1000Suns/p/11515585.html
Copyright © 2020-2023  润新知