1. 程式人生 > >JOISC 2018 Day 2 最差記者3

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;
}