题目:洛谷P1083 [NOIP2012 提高组] 借教室
emm,这波是换着平台乱刷了属实是
最近其实一直想练习线段树和差分,以及奇奇怪怪的二分法的应用,巧了刚好碰到一个题让我试试手了。
主要是
首先一波我直接暴力,45分,还不错,能拿分就行,笑死。
#include<bits/stdc++.h>
using namespace std;
int a[1000009];
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= m; i++)
{
int d, s, t;
cin >> d >> s >> t;
for (int j = s; j <= t; j++)
{
a[j] -= d;
if (a[j] < 0)
{
cout << -1 << endl << i;
return 0;
}
}
}
cout << 0;y
}
第二波,咱们来试试线段树,这题跟线段树好像,但是线段树好像真不行,因为我的线段树板子是用来查询区间和的,跟这题查询单个值不符。
接下来就是看题解学的第三波了,差分+二分,这样的话,以前复杂度是O(nm),现在复杂度就是O(n logm)了。
(u1s1再次感叹自己能力不行,自己能够想出来是这么做,但是自己在没看题解代码的情况下,还是没能仅凭自己一人把答案写出来)
#include<bits/stdc++.h>
using namespace std;
int a[1000009];
int b[1000009];
int tem[1000009];
vector<pair<int, pair<int, int>>> v;
int n, m;
int judge(int t)
{
memcpy(tem, b, sizeof(b));
for (int i = 0; i < t; i++)
{
int b1 = v[i].second.first;
int b2 = v[i].second.second;
int val = v[i].first;
tem[b1] -= val;
tem[b2+1] += val;
}
int z = 0;
for (int i = 1; i <= n; i++)
{
z += tem[i];
if (z < 0)
return 0;
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i] - a[i - 1];
}
for (int i = 1; i <= m; i++)
{
int d, s, t;
cin >> d >> s >> t;
v.push_back(make_pair(d, make_pair(s, t)));
}
int begin = 1, end = m;
if(judge(m))
cout << 0;
else
{
while (begin < end)
{
cout << begin << " " << end << endl;
int mid = (begin + end) / 2;
if (judge(mid))
begin = mid + 1;
else
end = mid ;
cout << begin << " " << end << endl;
}
cout << -1 << endl << begin ;
}
}