观察本题,我们发现,如果某些操作每次都更新到了某个位置,那么我们可以通过维护bitset来发现这个对于这个位置来说的可能最大值
而且答案就是所有位置取一下或。因为我们发现对于每个位置,bitset上为1的那些数一定可以取到最大值。
但是这样过于暴力,我们发现这是一个区间操作,而区间操作一般和线段树相结合,因此采用线段树分治,先对这段操作影响到的区间打标记
最后从根一直往下传递,就能把所有影响到每个位置的答案计算出来
初始化0这个位置是合法的
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,pll> plll; const int N=1e6+10; const int inf=0x3f3f3f3f; const int mod=1e9+7; bitset<10010> ans; bitset<10010> s; struct node{ int l,r; vector<int> num; }tr[N]; void build(int u,int l,int r){ if(l==r){ tr[u]={l,r}; } else{ tr[u]={l,r}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); } } void modify(int u,int l,int r,int k){ if(tr[u].l>=l&&tr[u].r<=r){ tr[u].num.push_back(k); return ; } int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,r,k); if(r>mid) modify(u<<1|1,l,r,k); } void dfs(bitset<10010> x,int u){ auto cur=x; for(auto a:tr[u].num){ cur|=(cur<<a); } if(tr[u].l==tr[u].r){ ans|=cur; return ; } int mid=tr[u].l+tr[u].r>>1; dfs(cur,u<<1); dfs(cur,u<<1|1); } int main(){ ios::sync_with_stdio(false); int n,q; cin>>n>>q; s[0]=1; build(1,1,n); while(q--){ int l,r,k; cin>>l>>r>>k; modify(1,l,r,k); } dfs(s,1); int cnt=0; for(int i=1;i<=n;i++){ if(ans[i]) cnt++; } cout<<cnt<<endl; for(int i=1;i<=n;i++){ if(ans[i]) cout<<i<<" "; } cout<<endl; return 0; }