一、差分

1.洛谷P1083借教室 (NOIP2012) https://www.luogu.com.cn/problem/P1083

比较显然的一种做法 : 求哪一天显然具有单调性,可以二分。那么每一次check的时候差分,总复杂度 O( n* log m )级别
code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 4;
int n,m;
ll r[maxn],s[maxn],t[maxn],d[maxn],tmp[maxn];
bool check(int x)
{
	for(int i=1;i<=n;i++) tmp[i]=0;
	for(int i=1;i<=x;i++) {
		tmp[s[i]]-=d[i];
		tmp[t[i]+1]+=d[i];
	}
	for(int i=1;i<=n;i++) {
		tmp[i]+=tmp[i-1];
		if(tmp[i]+r[i]<0) return true; 
	}
	return false;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&r[i]);
	for(int i=1;i<=m;i++) scanf("%lld%lld%lld",&d[i],&s[i],&t[i]);
	int l=1,r=m,mid,ans=m+1;
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(check(mid)) r=mid-1,ans=min(ans,mid);
		else l=mid+1;
	}
	if(ans!=m+1) printf("-1\n%d",ans);
	else printf("0");
	return 0;
}
学了一种做法 :O( n + m ) 的优秀复杂度 。 先做完差分,然后检查是否都符合要求,如果不符合,从后往前撤回订单,直到符合的位置即为答案。
code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 4;
ll r[maxn],s[maxn],t[maxn],d[maxn],f[maxn];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&r[i]);
	for(int i=1;i<=m;i++) {
		scanf("%lld%lld%lld",&d[i],&s[i],&t[i]);
		f[s[i]]+=d[i];
		f[t[i]+1]-=d[i];
	}
	int now=m,ans=m+1;
	ll sum=0;
	for(int i=1;i<=n;i++) {
		sum+=f[i];
		if(sum>r[i]) {
			while(sum>r[i]) 
			{
				f[s[now]]-=d[now];
				f[t[now]+1]+=d[now];
				if(s[now]<=i&&t[now]>=i) sum-=d[now];	
				now--;
			}
			ans=now+1;
		}
	}
	if(ans==m+1) printf("0");
	else printf("-1\n%d",ans);
	return 0;
}

二、单调栈

1.一个被坑过的题,比较典型的单调栈 https://blog.nowcoder.net/n/94a66c4dd8b249cab23928ceecc0da8c

2.2019牛客多校第八场 A 

题干 :
链接:https://ac.nowcoder.com/acm/contest/888/A
来源:牛客网
Gromah and LZR entered the great tomb, the first thing they see is a matrix of size n×m , and the elements in the matrix are all 0 or 1.

LZR finds a note board saying "An all-one matrix is defined as the matrix whose elements are all 1, you should determine the number of all-one submatrices of the given matrix that are not completely included by any other all-one submatrices".

Meanwhile, Gromah also finds a password lock, obviously the password should be the number mentioned in the note board!

Please help them determine the password and enter the next level.
分析 :

三、单调队列

1.经典题目——滑动窗口 https://www.luogu.com.cn/problem/P1886

分析 :head和tail动动动,滑滑滑
code :
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int a[maxn];
struct Node {
	int v,id;
}q[maxn],Q[maxn]; //其实只要一个就行了
int main()
{
	int n,k,head=1,tail=1;
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	Q[1].v=q[1].v=a[1];
	Q[1].id=q[1].id=1;
	for(int i=1;i<=n;i++) {
		while(head<=tail&&i-q[head].id>=k) head++;
		while(head<=tail&&q[tail].v>=a[i]) tail--;
		q[++tail].v=a[i];
		q[tail].id=i;
		if(i>=k) printf("%d ",q[head].v);
	}
	printf("\n");
	tail=1,head=1;
	for(int i=1;i<=n;i++) {
		while(head<=tail&&i-Q[head].id>=k) head++;
		while(head<=tail&&Q[tail].v<=a[i]) tail--;
		Q[++tail].v=a[i];
		Q[tail].id=i;
		if(i>=k) printf("%d ",Q[head].v);
	}
	return 0;
}

3.单调队列优化背包   NOI2005 瑰丽华尔兹 https://www.luogu.com.cn/problem/P2254