zoukankan      html  css  js  c++  java
  • 【BZOJ4408】[FJOI2016]神秘数(主席树)

    【BZOJ4408】[FJOI2016]神秘数(主席树)

    题面

    BZOJ
    洛谷

    题解

    考虑只有一次询问。
    我们把所有数排个序,假设当前可以表示出的最大数是(x)
    起始(x=0)
    依次考虑接下来的每个数(a_i),如果(a_ile x),那么没有啥问题,(x+=a_i)
    如果(a_i=x+1),那么也没有问题,(x+=a_i)
    如果(a_i>x),那么(x+1)就拼不出来了。
    那么显然考虑每次询问,首先把所有(le x)的数全部加进来,然后考虑下一个比(x)大的数,如果其大于(x+1),那么直接就(GG)了。
    否则等于(x+1),意味着(x)至少要翻一倍。
    因此最多执行(log)次翻倍的操作。
    抄起主席树暴力维护就好了。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MAX 100100
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    struct Node{int ls,rs,v;}t[MAX*35];int tot;
    void Modify(int &x,int l,int r,int p)
    {
    	t[++tot]=t[x];x=tot;t[x].v+=p;
    	if(l==r)return;int mid=(l+r)>>1;
    	if(p<=mid)Modify(t[x].ls,l,mid,p);
    	else Modify(t[x].rs,mid+1,r,p);
    }
    int Query(int x,int y,int l,int r,int p)
    {
    	if(l==r)return t[x].v-t[y].v;int mid=(l+r)>>1;
    	if(p<=mid)return Query(t[x].ls,t[y].ls,l,mid,p);
    	else return Query(t[x].rs,t[y].rs,mid+1,r,p)+t[t[x].ls].v-t[t[y].ls].v;
    }
    int n,m,a[MAX],rt[MAX];
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	for(int i=1;i<=n;++i)Modify(rt[i]=rt[i-1],1,1e9,a[i]);
    	m=read();
    	while(m--)
    	{
    		int l=read(),r=read(),x=0;
    		while(x<1e9)
    		{
    			int v=Query(rt[r],rt[l-1],1,1e9,x+1);
    			if(v==x)break;x=v;
    		}
    		printf("%d
    ",x+1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Hbuilder——报错The keyword 'export' is reserved
    控制器里路径变量的使用
    Spring 控制器重定向
    Spring A 标签链接使用
    Spring switch的使用
    thymeleaf如何遍历数据 each循环的使用
    spring 机制 扫描包
    Spring分层次建包
    什么是MVC模型
    如何运行spring boot 工程
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10489674.html
Copyright © 2011-2022 走看看