http://codeforces.com/problemset/problem/1073/D

题目大意:有n个物品(n<2e5)围成一个圈,你有t(t<1e18)元,每次经过物品i,如果身上的钱可以购买该物品就直接购买,直到一件物品都不能购买,求一共可以购买多少件物品.

题目分析:由于t的数量级达到了1e18,所以不可能直接进行暴力模拟,这个时候就要想到周期性地模拟.

题解:每次遍历一下1~n这n个物品,然后计算出可以取的物品数以及价值,然后用剩下的钱除以这个价值,得到可以进行的轮数,累加到结果中,然后继续遍历..继续累加...这个方法看起来还是很暴力,但是可以证明最多进行logTl轮,也就是总时间复杂度为O(N*logT).下面是轮数为logT的证明..

复杂度的证明:遍历之前的钱数记为Tcur,可以取走的物品价值记为C,遍历并且累加之后的钱数记为Tnex,则有Tnex=Tcur%C,则可以得到Tnex<C&&Tnex<=Tcur-C,所以Tnex<Tcur/2,所以可以得到能进行的轮数也就是logT,总的复杂度也就是O(N*logT)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,t,qwq[];
ll minn=1e12;
int main(){
//freopen("in.txt","r",stdin);
cin>>n>>t;
for(int i=;i<n;i++){
scanf("%lld",&qwq[i]);
minn=min(minn,qwq[i]);
}
ll ans=;
while(t>=minn){
ll k=;
ll kk=;
for(int i=;i<n;i++){
if(t>=qwq[i]){
t-=qwq[i];
k++;
kk+=qwq[i];
}
}
ans+=k+(t/kk)*k;
t%=kk;
}
cout << ans << endl;
return ;
}
04-29 04:22