您的位置:首页 > 其它

NOI2015 程序自动分析

2015-07-31 10:00 246 查看
题目大意:

给出一系列变量的等式约束和不等式约束,要求判定其中是否有矛盾;

变量下标最大值≤10^9;

约束数量≤10^5;

题解:

这是NOI2015最水的题了;

首先,分开等式约束和不等式约束;

等式约束用并查集保存;

不等式约束先用数组存着,等约束输入完毕后再判定是否与等式约束有矛盾;

即判断不等式两端变量是否属于同一集合

到这里,70分到手;

变量有10^9个?

空间只有512MB?

要是开10^9大小的并查集肯定爆空间;

但约束只有10^5个,即能用得到的变量最多只有2*10^5个;

网上说离散化,我是不懂的,离散化不是计算几何的吗?

uoj上一位哥们干脆上了个map;

即按输入的顺序给变量重新编号,

将重新编号后的变量的编号用于并查集中,原编号保存在map中,从而大大减少空间用量;

这样,每次并查集合并或查找根结点时都需要在map中按原编号查找新编号,用时O(logn);

总用时O(n*logn),n≤10^5,可以过;

于是,他的程序总用时2265ms,倒数第二,我用了AVL树,原倒数第二,hehe;

再考虑本题;

本题只用到了search(),和insert()操作,没有排序啊什么的;

考虑用链表维护的hash;

用一个2*10^5的数组T保存原编号;

再用一个2*10^5的数组next保存下一元素位置;

用一个p(模的数)大小的数组保存每个hash值对应链表的表头;

变量新编号就是它在T数组中的位置,例T[2015]=124785,那么124785的新编号为2015;

这样查找用时O(1),总用时O(n);

该算法在uoj上排名第三(前两个见鬼去吧),用时725ms;

注:uoj是一个相当好的oj,它支持浏览别人的代码,甚至可以通过hack来阻止别人的骗分代码拿到满分,

唯一的缺点就是题目较少(因为比较新);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息