站外题求助(可以吗)
  • 板块题目总版
  • 楼主NightTide
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/12/30 16:45
  • 上次更新2023/10/28 13:21:48
查看原帖
站外题求助(可以吗)
547908
NightTide楼主2021/12/30 16:45

题目:

Counting Sequences

For a set of sequences of integers{a1,a2,a3,...an}, we define a sequence{ai1,ai2,ai3...aik}in which 1<=i1<i2<i3<...<ik<=n, as the sub-sequence of {a1,a2,a3,...an}. It is quite obvious that a sequence with the length n has 2^n sub-sequences. And for a sub-sequence{ai1,ai2,ai3...aik},if it matches the following qualities: k >= 2, and the neighboring 2 elements have the difference not larger than d, it will be defined as a Perfect Sub-sequence. Now given an integer sequence, calculate the number of its perfect sub-sequence.

翻译

长度为n的整数序列,它有2n个子序列。如果子序列满足长度≥2, 而且任意相邻的两个整数的差的绝对值不大于d,称为完美子序 列。

求一个整数序列完美子序列的个数,结果对9901取模。

求助正文

一道 DP 题,在 DP 的基础上用线段树优化,但是 OJ 上一直都评测出运行错误,不知道为什么,发过来找大佬求助一下

#include<bits/stdc++.h>
#define MAXN 100010
#define MOD (ll)9901
using namespace std;
typedef long long ll;
struct node{
    /*
        l,r -> 区间
        val -> 区间和
    */
    ll l,r;
    ll val;
};
ll n,d,ans,len;
/*
    num 是原数据,tmp 用来离散化,里面存了 num[i], num[i]+d, num[i]-d
*/
ll tmp[MAXN*3],num[MAXN];
node tree[MAXN<<2];
void push_up(ll now){
    tree[now].val=tree[now*2].val+tree[now*2+1].val;
}
void build(ll now,ll l,ll r){
    tree[now].l=l; tree[now].r=r;
    if(tree[now].l==tree[now].r){
        tree[now].val=0;
        return ;
    }
    ll mid=(l+r)>>1;
    build(now*2,l,mid);
    build(now*2+1,mid+1,r);
    push_up(now);
}
/*
    updata(now,i,x) -> 在第 i 个位置上加上 x
*/
void updata(ll now,ll i,ll x){
    if(tree[now].l==tree[now].r){
        tree[now].val+=x; tree[now].val%=MOD;
        return ;
    }
    ll mid=(tree[now].l+tree[now].r)>>1;
    if(i<=mid) updata(now*2,i,x);
    else updata(now*2+1,i,x);
    push_up(now);
}
ll query(ll now,ll l,ll r){
    if(tree[now].l>=l&&tree[now].r<=r){
        return tree[now].val%MOD;
    }
    ll mid=(tree[now].l+tree[now].r)>>1;
    if(r<=mid) return query(now*2,l,r)%MOD;
    else if(l>mid) return query(now*2+1,l,r)%MOD;
    else return (query(now*2,l,mid)%MOD+query(now*2+1,mid+1,r)%MOD)%MOD;
}
int main(){
    while(~scanf("%lld%lld",&n,&d)){
        for(ll i=1;i<=n;i++){
            scanf("%lld",&num[i]);
            tmp[++len]=num[i];
            tmp[++len]=num[i]-d;
            tmp[++len]=num[i]+d;
        }
        sort(tmp+1,tmp+len+1);
        len=unique(tmp+1,tmp+len+1)-tmp-1;
        build(1,1,len); ans=0;
        for(ll i=1;i<=n;i++){
            ll now=num[i];
            ll val1=now-d,val2=now+d;
            //查找 num[i], num[i]-d, num[i]+d 离散化后对应的下标
            ll pos1=lower_bound(tmp+1,tmp+len+1,val1)-tmp;
            ll pos2=lower_bound(tmp+1,tmp+len+1,val2)-tmp;
            ll pos3=lower_bound(tmp+1,tmp+len+1,now)-tmp;
            ll sum=query(1,pos1,pos2);
            ans+=sum; ans%=MOD;
            updata(1,pos3,sum+1);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
2021/12/30 16:45
加载中...