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;
}
原文地址:https://www.cnblogs.com/sciorz/p/9156933.html