D - Destroyer Takahashi
题意:
给出 n 条线段,每条线段所处的位置为 [li,ri]
。
每次操作可以选择连续的m个位置,所有处于这 m 个位置的线段都会被消除。
问,最少多少次操作能将所有线段消除?
思路:
贪心:对于每段线段,当操作位置选在从其所处的最后一个位置向后延伸m位置时,对后面线段的贡献最大。
将所有线段按照末尾位置从小到大排序。
从前往后遍历每条线段:
- 如果其首位置再在消除的最后位置前面,那么这条线段已经可以被前面线段触发的操作消掉了。跳过。
- 如果没有,那么从末位置开始,往后的 m-1 个位置上的线段都会被消掉。更新最后位置。
Code:
const int N = 200010, mod = 1e9+7;
int T, n, m;
PII a[N];
bool cmp(PII a,PII b){
return a.se<b.se;
}
int main(){
Ios;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i].fi>>a[i].se;
sort(a+1,a+n+1,cmp);
int maxa=0,cnt=0;
for(int i=1;i<=n;i++)
{
if(a[i].fi<=maxa) continue;
cnt++;
maxa = a[i].se+m-1;
}
cout<<cnt;
return 0;
}
很妙的一道贪心题,之前也做过类似的,但是确实没想到。。
E - Fraction Floor Sum
题意:
求 i
从 1 到 n,n/i
下取整 之和。
思路:
能够证明,n/i
下取整所得数的种类不超过 2*sqrt(n)
种:
- 当 i ≤ s q r t ( n ) i ≤sqrt(n) i≤sqrt(n) 时,
i
都不会超过 sqrt(n) 种,那n/i
下取整也不会超过 sqrt(n) 种。 - 当 i > s q r t ( n ) i > sqrt(n) i>sqrt(n) 时,
n/i
的大小不会超过 sqrt(n),那其种类也不会超过 sqrt(n) 种。 所以,所得数的种类不会超过 2*sqrt(n)。
那么,可以将 i
从前往后遍历,每次找到所得值能够满足的最右边的 i
,答案+=所得值*长度,i
更新。
Code:
const int N = 200010, mod = 1e9+7;
int T, n, m;
int a[N];
int pd(int x)
{
int l=x,r=n;
while(l<r)
{
int mid=l+r+1>>1;
if(n/mid==n/x) l=mid;
else r=mid-1;
}
return l;
}
signed main(){
cin>>n;
int l=1,r=1;
int ans=0;
while(l<=n)
{
r=pd(l);
ans += (r-l+1)*(n/l);
l=r+1;
}
cout<<ans;
return 0;
}