luogu P4587 [FJOI2016]神秘数
我们 首先考虑暴力如何做。 现在最大的问题就是如何找出这个神秘数 先按升序排序,然后一个一个加数。 假设现在的值域是[1,pos],当前要加入的数是 x ; 不难发现,有两种情况: 若x>pos+1 , 那么一定拼不出pos+1,答案即为pos+1; 若1<= x <= pos+1 , 那么现在的值域就变成了[1,pos+x]; 这是最暴力的方法。。 优化: 考虑一段区间能够做出的贡献。 假设当前的值域为[1,pos],mx为上次用来更新值域时统计到的最大的范围 , 那么现在能做出贡献的一定有[mx+1,pos+1],统计出这段区间的sum。 (mx及之前的就不用统计了啦,因为在上一次更新值域时已经加过了) 现在的值域就变成了[1,pos+sum] , mx就变成了pos+1 ; 若sum==0,则说明[mx+1,pos+1]这段区间里没有数,那么答案就是pos+1啦(因为后面的数一定大于pos+1)。。 额,至于要快速找某段区间的某个范围的和,当然是主席树,然后就木有了。 Code #include<iostream> #include<cstdio> #define N 100010 using namespace std; int n,m,a[N],tot,root[N]; const int INF=1e9; struct Node{ int lc,rc,sum;