#loj6032. 「雅礼集训 2017 Day2」水箱
#loj6032. 「雅礼集训 2017 Day2」水箱
题目描述
给出一个长度为
输入格式
第一行一个正整数
第二行两个正整数
接下来一行
接下来
输出格式
共
输入数据 1
2
3 4
3 4
1 3 1
2 1 0
2 2 0
3 3 1
2 2
2
1 2 0
1 2 1
输出数据 1
3
1
数据范围与提示
对于
对于另外
对于另外
对于
Solution
这道题是道好题,做法有很多种。博客上有人提供了平衡树启发式合并的做法,也有用线段树优化
输入的时候将所有挡板的
然后就可以从下至上用扫描线一路扫上去,显然这样的耗时是
type=-1
此时的
type=0
此时的
type=1
此时的
其实看整个算法流程,很像树形 区间由线段组成,所以我们就叫它线段树形区间 。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<limits.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof(a));
using namespace std;
template<typename T> void read(T &k)
{
k=0;
T flag=1;char b=getchar();
while (b<'0' || b>'9') {flag=(b=='-')?-1:1;b=getchar();}
while (b>='0' && b<='9') {k=(k<<3)+(k<<1)+(b^48);b=getchar();}
k*=flag;
}
const int _SIZE=1e5;
int T,n,m;
struct EVENT{
int type,x,y;
}point[(_SIZE<<1)+5];
int tot;
int fa[_SIZE+5],f[_SIZE+5],ans[_SIZE+5],res;
bool cmp(EVENT a,EVENT b)
{
if (a.y!=b.y) return a.y<b.y;
if (a.type!=b.type) return a.type<b.type;
return a.x<b.x;
}
int find(int x)
{
if (fa[x]) return fa[x]=find(fa[x]);
return x;
}
void solve()
{
tot=0;mem(fa,0);mem(f,0);mem(ans,0);mem(point,0);
read(n),read(m);
for (int i=1;i<n;i++)
{
read(point[++tot].y);
point[tot].type=-1;
point[tot].x=i;
}
for (int i=1;i<=m;i++)
{
read(point[++tot].x);
read(point[tot].y);
read(point[tot].type);
}
sort(point+1,point+tot+1,cmp);
//system("pause");
res=0;
for (int i=1;i<=tot;i++)
{
int type=point[i].type,x=point[i].x;
if (type==-1)
{
int f_1=find(x),f_2=find(x+1);
fa[f_2]=f_1;
f[f_1]+=f[f_2];
ans[f_1]+=ans[f_2];
res=max(ans[f_1],res);
}
else if (!type)
res=max(res,++ans[find(x)]);
else
{
int f_=find(x);
++f[f_];
ans[f_]=max(ans[f_],f[f_]);
res=max(res,ans[f_]);
}
}
printf("%d\n",res);
}
int main()
{
read(T);
while (T--)
solve();
return 0;
}
我到底该把这道题放在什么标签下啊……
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步