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;
    }
    
  • 相关阅读:
    构建调试Linux内核网络代码的环境MenuOS系统
    stm32内存管理
    STM32CubeMx——ADC多通道采集
    STM32CubeMx——串口使用DMA收发数据
    STM32CubeMx——串口收发
    stm32CubeMx+TrueSTUDIO+uc/os-III移植开发(二)
    stm32CubeMx+TrueSTUDIO+uc/os-III移植开发(一)
    STM32F103RCT6移植到STM32F103C8T6注意事项
    关于STM32F103系列从大容量向中容量移植的若干问题
    KEIL软件中编译时出现的Error L6200E: symbol multiply defined ...的解决方法
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14980503.html
Copyright © 2011-2022 走看看