• BZOJ4408: [Fjoi 2016]神秘数&&4299: Codechef FRBSUM


    题解: 直接做肯定是不行的啦 我们考虑到这个性质 如果我们维护了mx为当前能表示连续的最大值 那么当我们插入的数x小于等于mx+1时都会接下来产生更长的连续区间 为什么大于mx+1不可以(因为你会中间漏掉几个数以至于无法表示) 因此转化模型为 求[l,r]区间在[lastmx+2,mx+1]范围权值的和 很显然主席树维护即可 然后更新mx 直到mx不在增加 此时mx+1就是我们所需要的答案 复杂度nlog^2n 更新mx的复杂度类似于斐波拉契数列的递增式 是收敛的

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=1e5+10;
    const int inf=1e9+7;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    ll read(){
    	ll x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    
    int n,a[MAXN],rt[MAXN],cnt,m,l,r,lastmx,mx;
    typedef struct node{
    	int l,r,sum;
    }node;
    node d[MAXN*41];
    void update(int &x,int y,int l,int r,int t){
    	x=++cnt;d[x]=d[y];d[x].sum+=t;
    	if(l==r)return ;
    	int mid=(l+r)>>1;
    	if(t<=mid)update(d[x].l,d[y].l,l,mid,t);
    	else update(d[x].r,d[y].r,mid+1,r,t);
    }
    ll ans;
    void querty(int x,int y,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr){ans+=d[y].sum-d[x].sum;return ;}
    	int mid=(l+r)>>1;
    	if(ql<=mid)querty(d[x].l,d[y].l,l,mid,ql,qr);
    	if(qr>mid)querty(d[x].r,d[y].r,mid+1,r,ql,qr);
    }
    int main(){
    	n=read();inc(i,1,n)a[i]=read(),update(rt[i],rt[i-1],1,inf,a[i]);
    	m=read();
    	while(m--){
    		l=read();r=read();lastmx=-1;mx=0;
    		while(1){
    			ans=0;querty(rt[l-1],rt[r],1,inf,lastmx+2,mx+1);
    			if(!ans)break;
    			lastmx=mx;mx+=ans;
    		}
    		printf("%d
    ",mx+1);
    	}
    }
    

     

    4299: Codechef FRBSUM

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 640  Solved: 402
    [Submit][Status][Discuss]

    Description

    数集S的ForbiddenSum定义为无法用S的某个子集(可以为空)的和表示的最小的非负整数。
    例如,S={1,1,3,7},则它的子集和中包含0(S’=∅),1(S’={1}),2(S’={1,1}),3(S’={3}),4(S’={1,3}),5(S' = {1, 1, 3}),但是它无法得到6。因此S的ForbiddenSum为6。
    给定一个序列A,你的任务是回答该数列的一些子区间所形成的数集的ForbiddenSum是多少。
     

    Input

    输入数据的第一行包含一个整数N,表示序列的长度。
    接下来一行包含N个数,表示给定的序列A(从1标号)。
    接下来一行包含一个整数M,表示询问的组数。
    接下来M行,每行一对整数,表示一组询问。
     

    Output

    对于每组询问,输出一行表示对应的答案。
     

    Sample Input

    5
    1 2 4 9 10
    5
    1 1
    1 2
    1 3
    1 4
    1 5

    Sample Output

    2
    4
    8
    8
    8

    HINT

    对于100%的数据,1≤N,M≤100000,1≤A_i≤10^9,1≤A_1+A_2+…+A_N≤10^9。

  • 相关阅读:
    Jquery $().each()与$.each(data,function(i,obj))区别
    「人生最好的境界」​​写出我心(九十)
    「金融市场里的推销」​写出我心(八十九)
    「错误」写出我心(八十八)
    「马丁路德·金的名言」写出我心(八十七)
    「眼界」​​​​​​​​​​​写出我心(八十六)
    「一个人真正成年的三大标志」写出我心(八十五)
    「如何降低事件对你的伤害」​​​​​​​​​​写出我心(八十四)
    「眼界的重要性」​​​​​​​​​写出我心(八十三)
    「平视所有优秀的人」​​​​​​​​写出我心(八十二)
  • 原文地址:https://www.cnblogs.com/wang9897/p/9618653.html
Copyright © 2020-2023  润新知