ACM学习历程—SNNUOJ 1239 Counting Star Time(树状数组 && 动态规划 && 数论)
2016-05-24 14:25
363 查看
http://219.244.176.199/JudgeOnline/problem.php?id=1239
这是这次陕西省赛的G题,题目大意是一个n*n的点阵,点坐标从(1, 1)到(n, n),每个点都有权值,然后从(x, y)引x轴的垂线,然后构成一个三角形,三个顶点分别是(0, 0),(x, 0)和(x, y)。求三角形内点的权值和,包括边界,n的范围是1000,m的范围是100000,说起来也比较坑。。学弟n*m的复杂度竟然水过去了,目测比赛数据比较水。。不过我挂到我们OJ上给了一组随机数据,一组极限数据,然后学弟就T掉了。。(坑学弟系列。。)
不水了,这个题目感觉本身是个很好的题。
刚拿到题,我的第一反应肯定是求出所有的p(x, y),然后往dp的转移方程去考虑。但是发现单纯的递推感觉问题更复杂了。。
但是发现一个重要点就是,斜率小的点,必定被它后面斜率大的点包括。然后,我就想到按x轴枚举每一列,维护每个斜率出现的权值和。那么每一个大的斜率必然是前面枚举过的小的斜率的和,于是便可以树状数组维护了。关键是解决斜率的离散化,我的第一想法是map来进行Hash。当时有了这个思路,本来想着应该可以抢个一血什么的。。结果打到一个小时左右的时候,发现这题已经被好几个人A掉了。。。(什么鬼。。)。我的第一发T了。。通过本地测试,map那个Hash实在太慢了。。于是我开始考虑怎么优化这个Hash,想了好几个办法,要满足y1/x1 < y2/x2,并且Hash(x1, y1) < Hash(x2, y2)的函数实在是没办法。。中间还交了两次错误的Hash方法。。最后队友提醒下,发现那个离散化的过程完全可以一开始预处理,不需要每组数据在线完成,因为数据只有1000*1000,那么所有斜率必然在这个范围内。然后终于A掉了。。
预处理复杂度:O(n*n*log(n*n))
打表:O(n*n*log(n*n))
在线查询:O(m)
最后总的复杂度是O(n*n*log(n*n)+T*(m+n*n*log(n*n)))
如果m大一点的话,这个复杂度还是比较优秀的。。
代码:
View Code
这是这次陕西省赛的G题,题目大意是一个n*n的点阵,点坐标从(1, 1)到(n, n),每个点都有权值,然后从(x, y)引x轴的垂线,然后构成一个三角形,三个顶点分别是(0, 0),(x, 0)和(x, y)。求三角形内点的权值和,包括边界,n的范围是1000,m的范围是100000,说起来也比较坑。。学弟n*m的复杂度竟然水过去了,目测比赛数据比较水。。不过我挂到我们OJ上给了一组随机数据,一组极限数据,然后学弟就T掉了。。(坑学弟系列。。)
不水了,这个题目感觉本身是个很好的题。
刚拿到题,我的第一反应肯定是求出所有的p(x, y),然后往dp的转移方程去考虑。但是发现单纯的递推感觉问题更复杂了。。
但是发现一个重要点就是,斜率小的点,必定被它后面斜率大的点包括。然后,我就想到按x轴枚举每一列,维护每个斜率出现的权值和。那么每一个大的斜率必然是前面枚举过的小的斜率的和,于是便可以树状数组维护了。关键是解决斜率的离散化,我的第一想法是map来进行Hash。当时有了这个思路,本来想着应该可以抢个一血什么的。。结果打到一个小时左右的时候,发现这题已经被好几个人A掉了。。。(什么鬼。。)。我的第一发T了。。通过本地测试,map那个Hash实在太慢了。。于是我开始考虑怎么优化这个Hash,想了好几个办法,要满足y1/x1 < y2/x2,并且Hash(x1, y1) < Hash(x2, y2)的函数实在是没办法。。中间还交了两次错误的Hash方法。。最后队友提醒下,发现那个离散化的过程完全可以一开始预处理,不需要每组数据在线完成,因为数据只有1000*1000,那么所有斜率必然在这个范围内。然后终于A掉了。。
预处理复杂度:O(n*n*log(n*n))
打表:O(n*n*log(n*n))
在线查询:O(m)
最后总的复杂度是O(n*n*log(n*n)+T*(m+n*n*log(n*n)))
如果m大一点的话,这个复杂度还是比较优秀的。。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <set> #include <queue> #include <map> #include <vector> #include <string> #define LL long long using namespace std; const int maxM = 1005; const int maxN = 1000005; LL d[maxN]; int lowbit(int x) { return x&(-x); } void add(int id, int pls) { while(id <= maxN)//id×î´óÊÇmaxN { d[id] += pls; id += lowbit(id); } } LL sum(int to) { LL s = 0; while(to > 0) { s = s + d[to]; to -= lowbit(to); } return s; } int gcd(int a, int b) { int r; while (b != 0) { r = b; b = a%b; a = r; } return a; } struct node { int x, y; void create(int xx, int yy) { int t = gcd(xx, yy); x = xx/t; y = yy/t; } bool operator<(node k) const { return k.x*y > k.y*x; } }; int n, a[maxM][maxM]; LL p[maxM][maxM]; int Hash[maxM][maxM]; bool vis[maxM][maxM]; void init() { memset(vis, false, sizeof(vis)); memset(Hash, 0, sizeof(Hash)); node t, k; priority_queue<node> q; int cnt = 1; for (int i = 1; i < maxM; ++i) { t.x = maxM-1; t.y = i; q.push(t); vis[t.x][t.y] = true; } while (!q.empty()) { t = q.top(); q.pop(); vis[t.x][t.y] = false; k.create(t.x, t.y); if (!Hash[k.x][k.y]) Hash[k.x][k.y] = cnt++; if (t.x > 1 && !vis[t.x-1][t.y]) { t.x--; q.push(t); vis[t.x][t.y] = true; } } } void input() { memset(d, 0, sizeof(d)); node t; int to; scanf("%d", &n); for (int i = n; i >= 1; --i) for (int j = 1; j <= n; ++j) scanf("%d", &a[i][j]); for (int j = 1; j <= n; ++j) { for (int i = 1; i <= n; ++i) { t.create(j, i); to = Hash[t.x][t.y]; add(to, a[i][j]); p[j][i] = sum(to); } } } void work() { int m, u, v; scanf("%d", &m); for (int i = 1; i <= m; ++i) { scanf("%d%d", &u, &v); printf("%lld\n", p[u][v]); } } int main() { //freopen("test.in", "r", stdin); //freopen("test.out", "w", stdout); init(); int T; scanf("%d", &T); for (int times = 1; times <= T; ++times) { printf("Case #%d:\n", times); input(); work(); } return 0; }
View Code
相关文章推荐
- 统计学里“P”的故事:蚊子、皇帝的新衣和不育的风流才子
- PowerPoint2007从网页导入文本
- java中的@repository什么意思?
- iOS学习之——懒加载
- c++的一些优化技巧
- IDA 调试 Android 方法及简单的脱壳实现
- webpack实战
- ScrollView的反弹效果
- Linux的inode的理解
- 如何安装VMware Tools 工具
- svn第三方库出现问题
- MySQL PHP基本指令
- IT人论房价 (二) 华为何逃离深圳,深圳怎么了
- Aappcloud 调到二级页面黑屏
- [STL]set/multiset用法详解[自从VS2010开始,set的iterator类型自动就是const的引用类型]
- MySQL 触发器
- Ubuntu使用Charles监控Android手机网络请求
- 嵌入式工程师待遇2016年行业调查
- 多程序共享摄像头
- 快速获取当天0点0分0秒(00:00:00),23点59分59秒(23:59:59)