NOIP2012 借教室 题解 洛谷P1083
2024-09-05 05:25:10
一看就是暴力
好吧,其实是线段树或差分+二分,这里用的是差分+二分的做法。
二分部分的代码,套个二分板子就行
int left=,right=m;
while(left<right)//二分
{
int mid=(left+right)>>;
if(check(mid)) left=mid+;
else right=mid;
}
差分
bool check(int x)//差分,判断
{
memset(f,,sizeof(f));
for(int i=;i<=x;i++)
{
f[l[i]]+=d[i];
f[r[i]+]-=d[i];
}
for(int i=;i<=n;i++)
{
g[i]=g[i-]+f[i];
if(a[i]<g[i])
return ;
}
return ;
}
完整代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int maxn=1e6+;
int a[maxn],l[maxn],r[maxn],d[maxn],f[maxn],g[maxn],n,m;
bool check(int x)//差分,判断
{
memset(f,,sizeof(f));
for(int i=;i<=x;i++)
{
f[l[i]]+=d[i];
f[r[i]+]-=d[i];
}
for(int i=;i<=n;i++)
{
g[i]=g[i-]+f[i];
if(a[i]<g[i])
return ;
}
return ;
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(),cout.tie();
cin>>n>>m;
for(int i=;i<=n;i++)
cin>>a[i];
for(int i=;i<=m;i++)
cin>>d[i]>>l[i]>>r[i];
if(check(n))
{
cout<<"";
return ;
}
else cout<<"-1"<<endl;
int left=,right=m;
while(left<right)//二分
{
int mid=(left+right)>>;
if(check(mid)) left=mid+;
else right=mid;
}
cout<<left;
return ;
}
最新文章
- cocos2d-x 图片性能测试
- 二模14day2解题报告
- [LintCode] Word Break
- Cent OS 常用 命令
- codeforce343A
- ubuntu14.04 Markdown编辑器推荐之Remarkable
- ElasticSearch(3)-原理
- margin:0 auto
- POJ 2084 Catalan数+高精度
- Android中selector的使用
- bzoj2096[Poi2010]Pilots 单调队列
- 嵌入式C快速翻转一个任何类型的数的二进制位
- 使用C#.NET列举组合数前N项和
- 关于VUE首屏加载过长的优化,VUE项目开发优化
- python学习路线--从入门到入土
- Linux系统初始配置标准化
- Thinkphp的S缓存用法!
- [UE4]使用C++重写蓝图,SpawnObject根据类型动态创建UObject
- gcc 动态编译 动态库路径
- mysql 替换