#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
const int INF = 2e9;
typedef pair<int,int> pii;
int n,len;
vector<pii> a;
bool check(int mid)
{
vector<pii> b;
for (auto &x: a)
{
int L = x.first , S = x.second;
if (S <= mid)
{
int t = mid - S; //mid时刻当前阀门已经流了t时间
int l = max(1ll,L - t), r= min(len,L + t); //mid时刻当前阀门对应的区间范围
b.push_back({l,r}); //将当前区间存下来
}
}
//做区间合并
sort(b.begin(),b.end());//一定要sort使得左端点升序
int st = -1, ed = -1;
for (auto &seg: b)
{
if (seg.first <= ed + 1) ed = max(ed,seg.second); //当前区间的左端点小于等于上一个区间的右端点+1,则作区间合并
else {
st = seg.first,ed = seg.second;//如果不是第一次使得st==1那就不行
// if(st!=1)return 0;
}
}
return st == 1 && ed == len; //若刚好能将整个管道覆盖,则返回true
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n >> len;
for (int i = 1;i <= n;i ++)
{
int l,s;
cin >> l >> s;
a.push_back({l,s});
}
int l = 0,r = INF;
//二分求最早满足覆盖整个管道的时刻
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid; // 在mid时刻已经覆盖整个管道,则答案一定在mid的左边(包括mid),二分左边
else l = mid + 1; //若不满足,则答案一定在mid的右边
}
cout << r << "\n";
return 0;
}
//区间合并模板题
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int n, m;
PII seg[N];
int main(){
cin >> m >> n;
for (int i = 0; i < n; i ++ ) cin >> seg[i].first >> seg[i].second;//区间的左右
sort(seg, seg + n);
int res = m + 1;
int st = seg[0].first, ed = seg[0].second;//定义开始和结束
for (int i = 1; i < n; i ++ ){//对于每一个区间
if (seg[i].first <= ed) ed = max(seg[i].second, ed);//如果可以合并就合并
else{
res -= ed - st + 1;//不能合并直接就减去上一个
st = seg[i].first, ed = seg[i].second;
}
}
res -= ed - st + 1;
cout << res << '\n';
return 0;
}
//多路归并
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e2 + 7;
int n, t, a[N], d[N], l[N], spend[N];
int get(int k) { // 在spend[i]的时间下在第个i鱼塘能调到的鱼的数量
return max(0LL, a[k] - d[k] * spend[k]); // 不可能出负数
// 修正:加上LL,确保比较的是long long类型
}
int work(int n, int t) { // 表示t分钟内
int res = 0;
memset(spend, 0, sizeof spend);
for (int i = 0; i < t; i++) {
int t = 1; // 先假设在第一个鱼塘钓的最多
for (int j = 2; j <= n; j++) {
if (get(t) < get(j)) t = j;
}
res += get(t);
spend[t]++; // 在这个鱼塘里面钓鱼的时间
}
return res;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
for (int i = 1; i <= n; ++i) {
cin >> d[i];
}
for (int i = 2; i <= n; i++) {
cin >> l[i];
l[i] += l[i - 1]; // 表示从第一个鱼塘到第i个鱼塘路上花的总时间
}
cin >> t;
int ans = 0;
for (int i = 1; i <= n; i++) {
if (t - l[i] >= 0) { // 修正:判断是否t-l[i]为负数
ans = max(ans, work(i, t - l[i]));
}
}
cout << ans << '\n'; // 修正:输出ans
return;
}
signed main() {
int tt = 1;
while (tt--) {
solve();
}
return 0;
}
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+7;
int n,m,sum=0;//sum用于记录全部的和
int a[N],b[N];
bool check(int mid){
int res=0;
for(int i=1;i<=n;i++){
if(a[i]>=mid){
res+=(a[i]-mid)/b[i]+1;//表示需要选择的次数
}
}
return res>=m;//与其他值扯上关系
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i]>>b[i];
int l=0,r=1e6;//表示每个技能可以升的能量树
while(l<r){
int mid=l+r+1>>1;
if(check(mid))l=mid;
else r=mid-1;
} //二分出来的r的意思是能量值>=r的都可以加上//可能冲覅
int ans=0,cnt=0;
for(int i=1;i<=n;i++){//如果起始的值>=r
if(a[i]>=r){
int c=(a[i]-r)/b[i]+1;//数量
int end=a[i]-(c-1)*b[i];
cnt+=c;//意思就是cnt可能一次加的超过m
ans+=(long long)(a[i]+end)*c/2;
}
}
cout<<ans-(cnt-m)*r;
return ;
}
signed main(){
int t=1;
while(t--)solve();
return 0;
}
(好难啊 真的好难啊 但是我一定要坚持!!!!! 呜呜呜呜呜真的好难啊
今天就这几个每日一题都写了快一天 加油吧!
请不要相信成功会像山坡的蒲公英一样唾手可得 但请相信世界上总有一些美好直到我们全力以赴 哪怕粉身碎骨!