离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
——————百度
你是否因为开数组过大而MLE
你是否因为不知道如何保存数值而WA到底
你是否从入门到放弃
不要担心不要害怕
离散化可以通过映射 将其简化。
那么就可以采用离散化来处理数据了
比如:
原数据: 999999, 1 , 24 , 3
离散化处理后: 4 , 1 , 3 , 2
在STL中有三个函数可以帮助我们进行以上操作
知道了这几个函数,离散化数据的操作就十分简单了。
我们需要另开一个数组来同时存放所需值,用来排序去重找到索引,再将索引赋值给原数组。
int a[MAXN],n; //原数组 数组长度
int b[MAXN],m; //索引数组 去重后的数组长度
/*数组赋值操作
....
....将两数组同时赋值
....
*/
sort(b,b+n);
m=unique(b,b+n)-b;
for(int i=0;i<m;i++)
a[i]=lower_bound(b,b+m,a[i])-b;
//离散化完成 进一步根据题意操作
从别人博客学到的: 离散化:两种离散化方式详解.
#include
const int MAXN=10;
using namespace std;
struct node{
int data,id;
}b[MAXN];
int a[MAXN],n;
bool rule(node x,node y)
{
return x.data<y.data;
}
int main()
{
for(int i=0;i<n;i++)
{
scanf("%d",&b[i].data);
b[i].id=i;
}
sort(b,b+n,rule);
for(int i=0;i<n;i++)
a[b[i].id]=i;
return 0;
}
题目分析
这数据妥妥的要离散化了,不过还需要一些并查集的知识。
AC代码
#include
using namespace std;
int t,n,ans,k,f[1000005],a[3*1000005],cnt,m;
struct node
{
int x,y,e;
}r[1000005];
bool rule(node a,node b)
{
return a.e>b.e; //合并的操作排在前
}
int find(int x)
{
if(f[x]==x) return x;
return f[x]=find(f[x]);
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
memset(r,0,sizeof(r));
memset(f,0,sizeof(f));
cnt=-1,ans=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&r[i].x,&r[i].y,&r[i].e);
a[++cnt]=r[i].x;
a[++cnt]=r[i].y;
}
sort(a,a+cnt);
m=unique(a,a+cnt)-a;
for(int i=0;i<=m;i++)
f[i]=i;
for(int i=1;i<=n;i++)
{
r[i].x=lower_bound(a,a+m,r[i].x)-a;
r[i].y=lower_bound(a,a+m,r[i].y)-a;
}
sort(r+1,r+1+n,rule);
for(int i=1;i<=n;i++)
{
int x=find(r[i].x);
int y=find(r[i].y);
if(r[i].e==1)
f[x]=y;
else{
if(x==y)
{
printf("NO\n");
ans=0;
break;
}
}
}
if(ans) printf("YES\n");
}
return 0;
}