zoukankan      html  css  js  c++  java
  • 洛谷 P4587 [FJOI2016]神秘数(主席树,dp)

    传送门


    解题思路

    今晚csp报名网站炸了QAQ,发布新闻者禁三警告
    先考虑暴力dp:
    O(na)的想必大家都会,但一遍都做不下来。
    所以需要换一种dp。
    假设求序列[l……r]的答案。
    先将其排序,假设到第i-1位时能表示出来的范围为[1..x],则只要判断第i位是否大于x+1即可。
    若小于x+1,则范围扩大到x+a[i],向下循环即可。

    然后用权值线段树维护区间和,变成主席树维护序列区间。

    最后时间复杂度为 (O(mlog^2a))

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    using namespace std;
    const int maxn=1e5+5;
    const int maxx=1e9+5;
    int n,m,cnt,rt[maxn];
    long long a[maxn];
    struct node{
    	int ls,rs;
    	long long  value;
    }d[maxn*40];
    void update(int &x,int last,int l,int r,long long v){
    	x=++cnt;
    	d[x]=d[last];
    	d[x].value+=v;
    	if(l==r) return;
    	int mid=(l+r)/2;
    	if(v<=mid) update(d[x].ls,d[last].ls,l,mid,v);
    	else update(d[x].rs,d[last].rs,mid+1,r,v);
    }
    long long query(int x,int y,int l,int r,long long v){
    	if(r<=v){
    		return d[y].value-d[x].value;
    	}
    	int mid=(l+r)/2;
    	long long res=0;
    	res+=query(d[x].ls,d[y].ls,l,mid,v);
    	if(v>mid) res+=query(d[x].rs,d[y].rs,mid+1,r,v);
    	return res;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    		update(rt[i],rt[i-1],1,maxx,a[i]);
    	}
    	cin>>m;
    	for(int i=1;i<=m;i++){
    		int l,r;
    		cin>>l>>r;
    		long long ans=1; 
    		while(1){
    			long long res=query(rt[l-1],rt[r],1,maxx,ans);
    			if(res<ans) break;
    			ans=res+1;
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Libvirt错误总结
    linux学习
    HMC 命令行登陆设置
    AIX扩VG和扩文件系统
    Bootstrap CSS2
    Bootstrap CSS
    JQuery的实例集合
    JQuery的noConflict()方法
    android的intent实现页面的跳转
    android的activity
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15399731.html
Copyright © 2011-2022 走看看