JOISC 2018 Day 2 最差记者3

JOISC 2018 Day 2 最差记者3

题意:

​ 数轴上有\(N\)个选手和一个旗手,旗手在位置\(0\)<第\(i\)人的位置为\(-i\),每个选手有一个参数\(D_i\)。旗手每单位时间向右走\(1\)单位,选手根据以下规则向右走:

  • 若与前一个人距离\(\le D_i\)\(i\)号选手不移动;
  • 若与前一个人距离\(> D_i\),则\(i\)号选手会立即向前走,走到距前者的后方\(1\)单位距离的位置。

\(Q\)组询问,每组询问给你\(T,l,i\),问在\(T\)时刻,数轴上\(l-r\)有多少人?(\(N,Q\leq1e5,D_i\leq1e9\)

题解:

​ 提高组题,每个人走的周期都是可以算的,如果这个人的周期少于上个人的周期,显然他的周期就和上个人的一样,否则他的周期\(f_i=\lceil \frac{f_{i-1}}{D_i} \rceil\)。然后这个函数的增长至少是两倍,直接存就好了。复杂度\(O(QlogD)\)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define of(i,l,r) for(int i=l;i>=r;i--)
#define fe(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,pii> piii;
inline void open(const char *s)
{
    #ifndef ONLINE_JUDGE
    char str[20];
    sprintf(str,"%s.in",s);
    freopen(str,"r",stdin);
//  sprintf(str,"%s.out",s);
//  freopen(str,"w",stdout);
    #endif
}
inline int rd()
{
    static int x,f;
    x=0;f=1;
    char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return f>0?x:-x;
}
int n,m;
vector<piii>v;

int main()
{
    n=rd();m=rd();
    ll d=1;int st=0;
    fo(i,1,n){
        int x=rd();
        if(x>d){
            v.push_back(piii(d,pii(st,i-1)));
            d=(ll)((x-1)/d+1)*d;st=i;
        }
    }
    v.push_back(piii(d,pii(st,n)));
    while(m--){
        ll T=rd(),l=rd(),r=rd(),ans=0;
        for(int i=0;i<(int)v.size();++i){
            ll ql=T/v[i].first*v[i].first-v[i].second.first;
            ll qr=ql-v[i].second.second+v[i].second.first;
            ans+=max(0ll,min(ql,r)-max(qr,l)+1ll);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/JackyhhJuRuo/p/10070092.html