codeforces 981-E. Addition on Segments

标签: 线段树


题目链接

https://codeforces.com/contest/981/problem/E

分析

在线段树的每个节点维护一个bitset.

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <bitset>
using namespace std;
typedef long long ll;
const int maxn=10050;
bitset<maxn> bin[maxn*4];
vector<int> lazy[maxn*4];
void build(){
    for(int i = 0; i < maxn*4; ++i) bin[i]=1;
}
bitset<maxn> one(1);
void update(int x,int y,int v,int l,int r,int id){
    if(l>=x&&r<=y){
        lazy[id].push_back(v);
        return;
    }
    int mid=(l+r)>>1;
    if(x<=mid) update(x,y,v,l,mid,id*2);
    if(y>mid) update(x,y,v,mid+1,r,id*2+1);
}
bitset<maxn> ans;
void dfs(int l,int r,int id){
    for(auto v:lazy[id]){
        bin[id]|=(bin[id]<<v);
        bin[id]|=(one<<v);
    }
    if(l==r) {
        ans|=bin[id];
        return;
    }
    bin[id*2]|=bin[id];
    bin[id*2+1]|=bin[id];
    int mid=(l+r)>>1;
    dfs(l,mid,id*2);
    dfs(mid+1,r,id*2+1);
}
const int N=10010;
int main(){
    int n,q;
    scanf("%d%d", &n,&q);
    build();
    while(q--){
        int l,r,v;
        scanf("%d%d%d", &l,&r,&v);
        update(l,r,v,1,N,1);
    }
    dfs(1,N,1);
    int c=0;
    for(int i = 1; i <= n; ++i) if(ans[i]) c++; 
    cout << c << endl;
    for(int i = 1; i <= n; ++i) if(ans[i]) cout << i << " ";
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sciorz/p/9156933.html