zoukankan      html  css  js  c++  java
  • CF981E Addition on Segments 线段树分治+bitset

    如果进行了 $q$ 个操作,且这 $q$ 个操作都包含位置 $i$,则 $i$ 位置的值一定是最大值.       

    所以我们就可以按照区间进行线段树分治,然后拿 bitset 优化一下 $dp$ 即可. 

    code: 

    #include <bits/stdc++.h> 
    #define N 10008  
    #define lson now<<1 
    #define rson now<<1|1   
    #define setIO(s) freopen(s".in","r",stdin)   
    using namespace std; 
    int n,q; 
    bitset<N>p,ans; 
    vector<int>g[N<<2];    
    void update(int l,int r,int now,int L,int R,int v) 
    {
    	if(l>=L&&r<=R) { g[now].push_back(v); return ; } 
    	int mid=(l+r)>>1;  
    	if(L<=mid)  update(l,mid,lson,L,R,v);  
    	if(R>mid)   update(mid+1,r,rson,L,R,v);    
    }
    void calc(int l,int r,int now,bitset<N>k) 
    {        
    	for(int i=0;i<g[now].size();++i) 
    	{      
    		int val=g[now][i];           
    		k|=(k<<val);   
    	}     
    	if(l==r) { ans|=k;  return ; } 
    	int mid=(l+r)>>1;      
    	calc(l,mid,lson,k),calc(mid+1,r,rson,k); 
    }
    int main() 
    {  
    	// setIO("input");  
    	scanf("%d%d",&n,&q);                 
    	for(int i=1;i<=q;++i) 
    	{
    		int l,r,x;  
    		scanf("%d%d%d",&l,&r,&x),update(1,n,1,l,r,x);  
    	}         
    	p[0]=1,calc(1,n,1,p);
    	int cnt=0; 
    	for(int i=1;i<=n;++i) if(ans[i]) ++cnt;  
    	printf("%d
    ",cnt);  
    	for(int i=1;i<=n;++i) if(ans[i]) printf("%d ",i);   
    	return 0; 
    }
    

      

  • 相关阅读:
    爬虫开头
    JAVA练习笔记---copyfile
    String
    十进制转化为八进制--栈实现
    一、给计算机专业的同学,计算机鸡汤
    数值的整数次方
    剪绳子-动态规划-贪婪
    二进制中为1 的数字个数
    机器人运动范围——回溯法应用
    矩阵的路径
  • 原文地址:https://www.cnblogs.com/guangheli/p/13023230.html
Copyright © 2011-2022 走看看