zoukankan      html  css  js  c++  java
  • #线段树分治,背包#CF601E A Museum Robbery

    题目

    (n) 个展品正在被展览,每一个展品都有一价值 (v) 个和一个混乱度 (w) ,现在有 (m) 次操作:

    1 (v) (w) :加入一个新的展品,价值为(v),混乱度为(w)

    2 (x) :删除第(x)个展品(一开始的展品也参与编号,且保证此展品此时存在)

    3 :进行询问

    (s(m)) 为询问时混乱度之和不超过m的展品集合价值的最大值,
    对于每一个询问,只需输出(sum_{m=1}^{k}s(m)*p^{m-1}pmod q)
    其中,(p=10^{7}+19,q=10^{9}+7)


    分析

    删除操作很难做,考虑线段树分治,
    对于每个时间点更新背包即可
    时间复杂度(O(mklog_2 m))


    代码

    #include <cstdio>
    #include <cctype>
    #include <vector>
    #include <cstring>
    #define rr register
    using namespace std;
    const int mod=1000000007,p=10000019;
    const int N=20011,M=1011;
    struct rec{int c,w,l,r;}q[N];
    int P[M],dp[M],n,m,T; vector<int>K[N<<2];
    inline signed iut(){
    	rr int ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f;
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    inline void update(int k,int l,int r,int x,int y,int z){
    	if (l==x&&r==y) {K[k].push_back(z); return;}
    	rr int mid=(l+r)>>1;
    	if (y<=mid) update(k<<1,l,mid,x,y,z);
    		else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
    		    else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
    }
    inline void dfs(int k,int l,int r){
    	rr int len=K[k].size(),f[M];
    	for (rr int i=0;i<len;++i){
    		rr rec t=q[K[k][i]];
    		for (rr int j=m;j>=t.w;--j)
    		    dp[j]=max(dp[j],dp[j-t.w]+t.c);
    	}
    	if (l==r){
    		rr int ans=0;
    		for (rr int j=1;j<=m;++j)
    		    ans=mo(ans,1ll*dp[j]*P[j-1]%mod);
    		print(ans),putchar(10);
    		return;
    	}
    	rr int mid=(l+r)>>1;
    	memcpy(f,dp,sizeof(f));
    	dfs(k<<1,l,mid);
    	memcpy(dp,f,sizeof(dp));
    	dfs(k<<1|1,mid+1,r);
    }
    signed main(){
    	P[0]=1;
    	for (rr int i=1;i<M;++i)
    	    P[i]=1ll*P[i-1]*p%mod;
    	n=iut(),m=iut();
    	for (rr int i=1;i<=n;++i) q[i]=(rec){iut(),iut(),0,-2};
    	for (rr int Q=iut();Q;--Q){
    		rr int opt=iut();
    		if (opt==3) ++T;
    		else if (opt==1)
    			q[++n]=(rec){iut(),iut(),T,-2};
    		else q[iut()].r=T-1;
    	}
    	for (rr int i=1;i<=n;++i) if (q[i].r==-2) q[i].r=T-1;
    	for (rr int i=1;i<=n;++i)
    	    if (q[i].l<=q[i].r)
    	        update(1,0,T-1,q[i].l,q[i].r,i);
    	dfs(1,0,T-1);
    	return 0;
    }
    
  • 相关阅读:
    计算机基础知识
    第三次作业函数
    c博客作业01顺序、分支结构
    C语言第02次作业循环结构
    c语言第0次作业
    JAVA在Eclipse里能运行,但是在cmd中却提示找不到主函数的错误【环境变量配置】
    MFC自定义消息机制步骤
    关于VC6.0界面MFC设置成XP风格问题【可以变得更加好看】
    VC6 下学习使用Teechart8记录 一 安装和熟悉teechart8【一个非常好的画图插件】
    Matlab中,让程序自动处理类似A1,A2,A3变量的方法。
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14980503.html
Copyright © 2011-2022 走看看