Meaning of the questions is clear. So jump directly to the idea.
Sol 1
The most violent wording is a direct enumeration of each parameter \ (W \) . Watched, but apparently not AC.
Sol 2
Noting \ (the Y \) is monotonic, i.e., as (W is \) \ increases and decreases . Thus obtaining binary value closest to the standard can be used \ (S \) two values. Block the following
bool ok1(long long x)
{
long long ans=check(x);//ans求的是Y的值
if (ans<S) return 0;else return true;//若y过大,则x取小了
}
.....
int main()
{
long long L=1,R=1000000;
while (L+1<R)
{
long long mid=(L+R)/2;
if (ok1(mid)) L=mid;else R=mid;
}//普通的二分
}
Using this method, time complexity is greatly reduced.
Sol 3
We spent most time-consuming sum, but whether it is \ (\ sum_j v_j \) or \ (\ sum_j 1 \) have Subtractivity , so we can use the prefix and to maintain the two, so you can with \ (O (n) \) modified and prefixed, \ (O (m) \) query time complexity is a qualitative leap. code show as below
#include<bits/stdc++.h>
using namespace std;
long long n,m,S,vis[300000],s[300000],l[300000],r[300000],v[300000],w[300000];
long long check(long long x)
{
long long ans=0;
for (long long i=1;i<=n;i++)
{
if (w[i]>=x) vis[i]=vis[i-1]+1,s[i]=s[i-1]+v[i];
else vis[i]=vis[i-1],s[i]=s[i-1];//判断的同时维护前缀和
}
for (long long i=1;i<=m;i++)
{
ans+=(vis[r[i]]-vis[l[i]-1])*(s[r[i]]-s[l[i]-1]);//O(1)求答案
}
return ans;
}
bool ok1(long long x)
{
long long ans=check(x);
if (ans<S) return 0;else return true;//上文已出现过
}
int main()
{
cin>>n>>m>>S;
for (long long i=1;i<=n;i++)
{
cin>>w[i]>>v[i];
}
for (long long i=1;i<=m;i++)
{
cin>>l[i]>>r[i];
}
long long L=1,R=1000000;
while (L+1<R)
{
long long mid=(L+R)/2;
if (ok1(mid)) L=mid;else R=mid;
}//前面已出现过
cout<<min(check(L)-S,S-check(R))<<endl;//以L为参数的答案大于S,以R为参数的小于S
return 0;
}
postscript
This problem also a similar topic P1083 borrow the classroom , the same as NOIP title, interested students can write.