[ARC101F]ロボットと終了しフェンウィックツリーの最適化DP

フェイス質問



\(溶液:\)

まず書き込むための夕食後、つぶやきました。



\(コード:\)

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define rg register int

using namespace std;

const int mod=1e9+7;//998244353;

int n,m;
int tt,ans=1; //注意赋了初值1
int a[500005];
int b[500005];
int k[500005]; //离散化
int f[500005]; //计数
int tr[500005]; //树状数组

struct su{
    int x,y;
    inline bool operator <(const su &z)const{
        if(y==z.y)return x>z.x;
        return y<z.y;
    }
}s[500005];

inline int qr(){
    register char ch; register bool sign=0; rg res=0;
    while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
    while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
    if(sign)return -res; else return res;
}

inline void add(int x,int v){ //树状数组加入
    for(;x<=tt;x+=x&-x) (tr[x]+=v)%=mod;
}

inline int ask(int x){ //树状数组查询
    rg res=0;
    for(;x;x-=x&-x) (res+=tr[x])%=mod;
    return res;
}

int main(){
    //freopen("robot.in","r",stdin);
    //freopen("robot.out","w",stdout);
    n=qr(); m=qr();
    for(rg i=1;i<=n;++i) a[i]=qr();
    for(rg i=1;i<=m;++i) b[i]=qr(); //已经按顺序排序
    for(rg i=1,j=1;i<m&&j<=n;++i){
        while(j<=n&&a[j]<=b[i])++j; //找到中间的第一个机器人
        if(j>n)break;
        while(j<=n&&a[j]<b[i+1]){ //遍历所有在中间的机器人
            k[++tt]=a[j]-b[i]; //k数组是用来离散化的
            s[tt]=su{k[tt],b[i+1]-a[j]}; ++j; //记录左右距离
        }
    } sort(k+1,k+tt+1); //离散化
    for(rg i=1;i<=tt;++i)
        s[i].x=lower_bound(k+1,k+tt+1,s[i].x)-k; //离散化
    sort(s+1,s+tt+1); //按纵坐标从小到大,横坐标从大到小
    for(rg i=1;i<=tt;++i){
        if(s[i].x==s[i-1].x&&s[i].y==s[i-1].y)continue; //去重!
        f[i]=(ask(s[i].x-1)+1)%mod; //只有横坐标比它小的才可以转移
        ans=(ans+f[i])%mod; //计入答案
        add(s[i].x,f[i]); //加入树状数组
    }
    printf("%d\n",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/812-xiao-wen/p/11299126.html