zoukankan      html  css  js  c++  java
  • Jzoj4710 Value

    题意:有n([1,5000])个物品,每一个有价值v和代价w,当你选择了这个物品后,剩下没选的物品价值减少w,问最大价值?

    假设我们已经选好了物品,那么显然,按照w升序排序贪心是最优的选择

    让后我们可以用dp来计算最优方案,这样的话我们需要将物品按照w降序排序,否则无法计算转移时的价值变化量

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define f(k) (1ll<<k)
    #define g(k) (f(k+1)-1)
    using namespace std;
    int w[22][1<<20],n,m,v[100010];long long A=0;
    inline void add(int i,int x,int k){ for(++x;x<=f(i+1);x+=x&-x) w[i][x]+=k; }
    inline int sum(int i,int x,int s=0){ for(++x;x;x^=x&-x) s+=w[i][x]; return s; }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int x,i=1,j;i<=n;++i){
    		scanf("%d",v+i);
    		for(int j=0;j<20;++j) add(j,v[i]&g(j),1);
    	}
    	for(int o,x,y;m--;){
    		scanf("%d%d%d",&o,&x,&y);
    		if(o==1){
    			for(int j=0;j<20;++j)
    				add(j,v[x]&g(j),-1),add(j,y&g(j),1);
    			v[x]=y;
    		} else {
    			A=0;
    			for(int j=0;j<20;++j) if(y&f(j)){
    				int l=f(j)-1,r=g(j);
    				l=(l-x+f(20))&g(j);
    				r=(r-x+f(20))&g(j);
    				if(l<=r) A+=f(j)*(sum(j,r)-sum(j,l));
    				else A+=f(j)*(sum(j,r)+sum(j,f(j+1))-sum(j,l));
    			}
    			printf("%lld
    ",A);
    		}
    	}
    }

  • 相关阅读:
    南邮NOJ没有被接待的童鞋
    南邮NOJ 1014 数据的插入与删除
    Absolute C++ 2.10题目
    Absolute C++ 2.10题目
    Absolute C++ 2.10题目
    Absolute C++ 2.10题目
    南邮NOJ开灯问题
    南邮NOJ偷吃可耻
    【HDOJ】1166 敌兵布阵
    【HDOJ】1180 诡异的楼梯
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477311.html
Copyright © 2011-2022 走看看