http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=886
这个榜歪到天上去了,LCT过120队,这题线段树裸题过30+队
这题就是dp[i]只能从dp[i-R]---dp[i-L]这段转移过来,那么对前缀和离散化一下,把前缀和当下标维护一棵权值线段树,记录区间段最大的dp值,注意这题由于可能有重复的前缀和,所以不要unique,就是排序然后就可以让一个位置的sum[i]确定一个下标,就不用考虑重复的问题了。
然后转移的时候就分3中情况,sum[i]-sum[j]<0,=0,>0,lower_bound,upper_bound搞搞看从线段树哪个区间的最大值转移过来。
i向后移,就把i-R从权值线段树中删了,把i-L+1加进权值线段树
#include
namespace FastIO {
const int SIZE = 1 << 16;
char buf[SIZE], obuf[SIZE], str[60];
int bi = SIZE, bn = SIZE, opt;
int read(char *s) {
while (bn) {
for (; bi < bn && buf[bi] <= ' '; bi++);
if (bi < bn) break;
bn = fread(buf, 1, SIZE, stdin);
bi = 0;
}
int sn = 0;
while (bn) {
for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
if (bi < bn) break;
bn = fread(buf, 1, SIZE, stdin);
bi = 0;
}
s[sn] = 0;
return sn;
}
bool rd(int& x) {
int n = read(str), bf;
if (!n) return 0;
int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
if (bf < 0) x = -x;
return 1;
}
};
using namespace FastIO;
using namespace std;
const int maxl=2e6+10;
const int inf=2e9+10;
int n,L,R,cnt,tot;
int a[maxl],c[maxl],sum[maxl],dp[maxl];
int id[maxl];
struct ind
{
int val,id;
}b[maxl];
struct node
{
int l,r,mx;
}tr[maxl<<2];
inline void build(int k,int l,int r)
{
tr[k].l=l;tr[k].r=r;tr[k].mx=-inf;
if(l==r)
return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
inline bool cmp(const ind &a,const ind &b)
{
return a.val>1;
if(l<=mid)
upd(k<<1,l,x);
else
upd(k<<1|1,l,x);
tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
}
inline int qry(int k,int l,int r)
{
if(tr[k].l==l && tr[k].r==r)
return tr[k].mx;
int mid=(tr[k].l+tr[k].r)>>1;
if(r<=mid)
return qry(k<<1,l,r);
else if(l>mid)
return qry(k<<1|1,l,r);
else
return max(qry(k<<1,l,mid),qry(k<<1|1,mid+1,r));
}
inline void mainwork()
{
int hd=0,tl=-1,l,r;
dp[0]=0;
for(int i=1;i<=n;i++)
{
dp[i]=-inf+1;
if(hd1)
dp[i]=max(dp[i],qry(1,1,l-1)+1);
}
}
inline void print()
{
printf("%d\n",dp[n]);
}
int main()
{
int t;
//scanf("%d",&t);
rd(t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}