考虑每个点i在什么情况下会成为最大值。 当选的区间子集是 包含i的区间的一个子集的时候,i肯定会是最大值。 所以我们就可以用这种方法得到所有点的可能的最大值是多少。。。

 

    也就是说,最后的局面可以仅由一个从左到右扫一遍时单峰的区间子集构成,这样不会丧失任意一个可行解。。。。

 

 

 

    于是就可以直接线段树打标记+bitset优化可行背包问题。。。。暴力跑一遍就能A啦。。。。

 

 

Discription

Grisha come to a contest and faced the following problem.

You are given an array of size li,li+1,…,ri. After all operations you should find the maximum in the array.

Grisha is clever, so he solved the problem quickly.

However something went wrong inside his head and now he thinks of the following question: "consider we applied some subset of the operations to the array. What are the possible values of the maximum in the array?"

Help Grisha, find all integers y.

Input

The first line contains two integers 1≤n,q≤104) — the length of the array and the number of queries in the initial problem.

The following ri-th elements of the array, inclusive.

Output

In the first line print the only integer n, inclusive, that can be equal to the maximum in the array after applying some subset (possibly empty) of the given operations.

In the next line print these increasing order.

Examples

Input
4 3
1 3 1
2 4 2
3 4 4
Output
4
1 2 3 4
Input
7 2
1 5 1
3 7 2
Output
3
1 2 3
Input
10 3
1 1 2
1 1 3
1 1 6
Output
6
2 3 5 6 8 9

 

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=10005;
#define pb push_back
#define lc (o<<1)
#define mid (l+r>>1)
#define rc ((o<<1)|1)
vector<int> tag[maxn*4];
int n,m,le,ri,w,Q,num;
bitset<maxn> ans,E;

void update(int o,int l,int r){
	if(l>=le&&r<=ri){ tag[o].pb(w); return;}
	if(le<=mid) update(lc,l,mid);
	if(ri>mid) update(rc,mid+1,r);
}

void dfs(int o,bitset<maxn> y,int len){
	bitset<maxn> z=y;
	for(int i=tag[o].size()-1;i>=0;i--){
		z|=(z<<tag[o][i]);
	}
	
	if(len==1) ans|=z;
	else dfs(lc,z,len-(len>>1)),dfs(rc,z,len>>1);
}

int main(){
	scanf("%d%d",&n,&Q);
	
	for(int i=1;i<=Q;i++){
		scanf("%d%d%d",&le,&ri,&w);
		update(1,1,n);
	}
	
	E[0]=1,dfs(1,E,n);
	
	for(int i=1;i<=n;i++) if(ans[i]) num++;
	printf("%d\n",num);
	for(int i=1;i<=n;i++) if(ans[i]) printf("%d ",i);
	puts("");
	return 0;
}

  

相关文章: