题目链接:http://codeforces.com/contest/981/problem/E
思路:因为是查询的子集,所以其实只要看这些子集能凑出那些数字就好了,每次查询是l,r,x相当于l-r每个点加x,所以很容易可以想到用1-n之间每一个点bitset一次看有多少种数字,可如果真这么干了,肯定要T掉,所以可以配合线段树加速一下。
然后我用了bitset,#define rc (d<<1|1)这条编译就出错了,很迷,不知道为什么。。。。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%I64d",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod int(1e9+7)
#define lc (d<<1)
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
int n,q;
bitset<10008> s[10008<<2];
vector<int>g[10008<<2];
struct as{
int l,r;}tr[10008<<2];
void build(int d,int l,int r)
{
tr[d].l=l,tr[d].r=r,s[d][0]=1;
if(l==r) return;
int mid=(l+r>>1);
build(lc,l,mid);
build((d<<1|1),mid+1,r);
}
void add(int d,int l,int r,int x)
{
if(tr[d].l==l&&tr[d].r==r)
{
g[d].push_back(x);
return;
}
int mid=(tr[d].l+tr[d].r>>1);
if(r<=mid) add(lc,l,r,x);
else if(l>mid) add((d<<1|1),l,r,x);
else add(lc,l,mid,x),add((d<<1|1),mid+1,r,x);
}
void query(int d,int l,int r)
{
if(l==r) {for(int i=0;i<g[d].size();i++) s[d]|=s[d]<<g[d][i];return;}
int mid=(tr[d].l+tr[d].r>>1);
if(r<=mid) query(lc,l,r);
else if(l>mid) query((d<<1|1),l,r);
else query(lc,l,mid),query((d<<1|1),mid+1,r);
s[d]|=s[lc],s[d]|=s[(d<<1|1)];
for(int i=0;i<g[d].size();i++) s[d]|=s[d]<<g[d][i];
}
int main()
{
cin.tie(0);
cout.tie(0);
cin>>n>>q;
int x,y,z,zs=0;
build(1,1,n);
while(q--)
{
si(x),si(y),si(z);
add(1,x,y,z);
}
query(1,1,n);
FOR(i,1,n) if(s[1][i]) zs++;
cout<<zs<<endl;
FOR(i,1,n) if(s[1][i]) cout<<i<<" ";
return 0;
}