B - Wonderful Array (暑假训练赛)

原题链接

 

Input

The first line contains an integer kk (1≤k≤106)(1≤k≤106).

 

The second line contains kk integers a0,a1,...,ak−1a0​,a1​,...,ak−1​ (1≤ai≤109)(1≤ai​≤109).

The third line contains three integers n,m,xn,m,x (1≤n≤109,1≤m≤109,1≤x≤109)(1≤n≤109,1≤m≤109,1≤x≤109).

Output

Output a single integer, denoting the answer.

Sample 1

InputcopyOutputcopy
3
2 4 3
4 7 5
2

Note

 

思路:

要求的是bi<=bi+1的个数,对于i=[0,n-1],我们求这个个数其实是不好求的,即使是==的个数就是求有多少个位置b[i]%m==0, 即使用暴力去跑,也会TLE在test3数据

所以通过证难则反的思想要求<=那么直接求>的个数在减去不就是答案了吗

由于比大小的时候都是对m取余的,因此,就全部都先预处理一波,将x,b0,b1,b2....都对m取余一次。这个时候,我们假设i-1是ant,那么第i个数值就是ant+a[i%k]。此时就会发现如果这样求下来大于m的话取模之后必然小于ant。(想一下加上都是已经对m取余的数,即使俩俩相加也会小于前一个,例子m=3时 i-1=2 a[i%k]=2,这样情况下不就是会一定会小于吗 )。因为我们加上的这个数a[i%k]是比m小的,所以这个结果是res%m>(res+a[i%k])%m,所以这是一个>的合法解。此时就会发现只要找到满足这样的所有的情况,那么就是答案,这个时候我们每次加的都是比m小的,所以只要bn中有几个m的倍数,就会出现几个这种>情况,所以我们只需要求出来bn是多少,然后除m就是>的情况,所以n-bn/m就是<=的情况

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<stack>
#include<string>
#include<algorithm>
#include<unordered_map>
#include<map>
#include<cstring>
#include <unordered_set>
//#include<priority_queue>
#include<queue>
#include<set>
#include<stdlib.h>
#define dbug cout<<"hear!"<<endl;
#define rep(a,b,c) for(ll a=b;a<=c;a++)
#define per(a,b,c) for(ll a=b;a>=c;a--)
#define no cout<<"NO"<<endl;
#define yes cout<<"YES"<<endl;
#define endl "\n"
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//priority_queue<int,vector<int>,greater<int> >q;
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> PII;
typedef pair<long double,long double> PDD;
const ll  INF = 0x3f3f3f3f;
//const ll LINF=LLONG_MAX;
// ll gcdd(ll a, ll b)
// {
//       while(b^=a^=b^=a%=b);    
//       return a;
// }
// ll lcmm(ll a,ll b)
// {
//     ll ans;
//     ans=a/gcdd(a,b)*b;
//     return ans;
// }

 
//ll idx;
const ll N = 2e6+ 10;
const ll mod =998244353;
ll t,n,m,x,y,ca;
ll arr[N],brr[N], crr[N];
ll book[N];
vector<ll>ve;
ll ne[N],e[N],w[N];
ll h[N],idx;
void add(ll a,ll b, ll c)
{
  e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}

void solve()
{
  ll k;
  scanf("%lld",&k);
  rep(i,0,k-1)scanf("%lld",&arr[i]);
  scanf("%lld%lld%lld",&n,&m,&x);
  rep(i,0,k-1)arr[i]%=m;
  x%=m;
  brr[0]=x;
  rep(i,1,k)
  {
    brr[i]=brr[i-1]+arr[i-1];
  }
  ll ant=(n/k)*k;
  ll sum=brr[k]-brr[0];
  ll res=sum*(n/k)+x;
  rep(i,ant+1,n) res+=arr[i-ant-1];
  ll ans=n-res/m;
  printf("%lld",ans);
}
int main()
{
    //IOS;
    t=1;
    //scanf("%d",&t);
    //cin>>t;
    ca=1;
    while(t--)
    {
      solve(); 
      ca++;
    }    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值