https://www.zybuluo.com/ysner/note/1335090
题面
解析
一开始想了一个读入完再处理的暴力方法,比较麻烦。
其实可以考虑增量地看待这个问题。
如果当前客栈(valleq p),则前面所有同色客栈都可为(ans)作出(1)的贡献。
否则,就是上一个(valleq p)的客栈出现前,前面所有同色客栈的数量。
所以我们对每种颜色统计两个量:
- 前面所有同色客栈的数量(num)
- 上一个(valleq p)的客栈出现前,前面所有同色客栈的数量(res)
每当碰到一个(valleq q)时,可以把所有(res)更新为(num)。
然后每次答案加上同色的(res)即可。
然而有个细节,在(valleq q)时,当前点对答案没贡献,对(res)有贡献。
复杂度(O(nk))。
也可以优化到(O(n))。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;++i)
#define fq(i,a,b) for(re int i=a;i>=b;--i)
using namespace std;
const int N=55;
int n,k,p,num[N],las[N],now;
ll ans;
il ll gi()
{
re ll x=0,t=1;
re char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*t;
}
il int min(re int x,re int y){return x<y?x:y;}
int main()
{
n=gi();k=gi();p=gi();
fp(i,1,n)
{
re int col=gi(),val=gi();
if(val<=p)
fp(j,0,k-1) las[j]=num[j];
ans+=las[col];
if(val<=p) ++las[col];
++num[col];
}
printf("%lld
",ans);
return 0;
}