UVALive 7343 H - Design New Capital
2016-01-19 10:31
344 查看
题目描述:
If you go through history you will come across many fun facts about the capital city of a country.In many countries the most famous or most populated or most industrialized cities are not declared
capital. For example, Zurich or Geneva is not capital of Switzerland it is Berne. In Australia the capital
is neither Melbourne nor Sydney, it is Canberra and guess what Canberra was built to be capital! In
Brazil Brasilia is capital not Rio.
Head of your country decided to redesign the capital. Dr. Krakow is appointed as the head architect
of this project. Having been in Europe and America, he has vast experience about city life. He wants
to lay roads like New York. That is, if you see from above, it will look like a big 2d grid. He wants
to build the parliament at (0, 0) coordinate of this grid. After that, he asks some people where would
they love to stay. Of course, it is not possible to allow to build homes anywhere the people like. There
are many constraints to consider. One of the constraints is the parliament has to be at the optimal
position. A position is optimal if summation of Manhattan distance to all the houses from the position
is minimum.
For example, suppose there are three proposals to build houses at following positions: (1, 1), (−1, −1)
and (2, 2). If Dr. Krakow approves to build houses at (1, 1) and (−1, −1) then (0, 0) would be optimal
position. But if he approves (1, 1) and (2, 2) then (0, 0) is no more optimal position. Please note, there
may be many optimal positions for some set of approval, but (0, 0) has to be one of them. Given some
proposals, help Dr. Krakow to figure out number of ways he can approve some of the proposals so that
parliament is at one of the optimal positions. Please note, there may be request for the same place
from different persons. In such case Dr. Krakow can approve none or all or some of these proposals.
When computing summation of Manhattan distance, all of the approved proposals are counted, that is,
if there are two approved proposals at the same place, then distance from this place to the parliament
will be counted twice.
Input
The first line of the input will contain a positive integer T (T ≤ 5). Hence T cases follow.
First line of the test case contains number of proposals n (1 ≤ n ≤ 105
). Hence n liness follow, each
describing a proposal x, y (−109 ≤ x, y ≤ 109 and xy ̸= 0).
Output
For each case print case number followed by space separated n numbers where i-th of these numbers
denotes number of ways you can accept i proposals. Since the answer can be very big you need to
present the solution in modulo 7340033.
题解:
1.其实就是中位数.2.显然奇数不可能,偶数的话是对称4个区域有关系.
3.可以写出公式之后, 发现时卷积,用NTT
重点:
1.中位数,再推,写出公式来优化2.NTT
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int M = 7340033; const int maxn = 5e5 + 100; const int key = 100000; int c[5][maxn], num[5]; int a1[maxn], a2[maxn]; int x1[maxn], x2[maxn]; int rev[maxn], n; int add(int a, int b) { int c = a + b; if(c >= M) c -= M; return c; } int sub(int a, int b) { if(a < b) a += M; return a - b; } int power(int x, int n) { int res = 1, tmp = x % M; while(n) { if(n & 1) res = (ll)res * (ll)tmp % M; tmp = (ll)tmp * (ll)tmp % M; n >>= 1; } return res; } int inverse(int x) { return power(x, M - 2); } void change(int y[], int len) { int i, j, k; for(i = 1, j = len / 2; i < len - 1; i++) { if(i < j) swap(y[i], y[j]); k = len / 2; while(j >= k) { j -= k; k /= 2; } if(j < k) j += k; } } void fft(int y[], int len, int on) { change(y, len); for(int h = 2; h <= len; h <<= 1) { int unit_p0 = power(3, (M - 1) / h); if(on == -1) unit_p0 = inverse(unit_p0); for(int j = 0; j < len; j += h) { int unit = 1; for(int k = j; k < j + h / 2; k++) { int u = y[k]; int t = (ll)unit * (ll)y[k + h / 2] % M; y[k] = add(u, t); y[k + h / 2] = sub(u, t); unit = (ll)unit * (ll)unit_p0 % M; } } } if(on == -1) { int key = inverse(len); for(int i = 0; i < len; i++) { y[i] = (ll)y[i] * (ll)key %M; } } } void solve() { for(int i = 0; i < 4; i++) { int a = num[i]; c[i][0] = 1; for(int j = 1; j <= key; j++) { if(j > a) c[i][j] = 0; else { c[i][j] = (ll)c[i][j - 1] * (ll)(a - j + 1) % M * (ll)rev[j] % M; } } } memset(a1, 0, sizeof(a1)); memset(a2, 0, sizeof(a2)); for(int i = 0; i <= key; i++) { a1[i] = (ll)c[0][i] * (ll)c[2][i] % M; a2[i] = (ll)c[1][i] * (ll)c[3][i] % M; } int len = key; int len1 = 1; while(len1 <2 * len) { len1 *= 2; } fft(a1, len1, 1); fft(a2, len1, 1); for(int i = 0; i < len1; i++) { a1[i] = (ll)a1[i] * (ll)a2[i] % M; } fft(a1, len1, -1); for(int i = 1; i <= n; i++) { if(i % 2 == 1) printf("0"); else printf("%d", a1[i / 2]); if(i != n) printf(" "); else printf("\n"); } } int main() { //freopen("h.txt", "r", stdin); for(int i = 1; i <= key; i++) rev[i] = inverse(i); int ncase; scanf("%d", &ncase); for(int _ = 1; _ <= ncase; _++) { printf("Case %d:\n", _); scanf("%d", &n); memset(num, 0, sizeof(num)); for(int i = 1; i <= n; i++) { int x, y; scanf("%d%d", &x, &y); if(x >= 0 && y >= 0) num[0]++; if(x <= 0 && y >= 0) num[1]++; if(x <=0 && y <= 0) num[2]++; if(x >=0 && y <= 0) num[3]++; } solve(); } return 0; }
相关文章推荐
- MySQL创建用户的三种方法
- 操作MySQL数据库的文章
- Linux文件权限
- Caffe学习系列(21):caffe图形化操作工具digits的安装与运行
- 导入的js文件报错,很奇怪
- 行内人解读开发一个App需要多少钱?
- OpenCV3.1.0+VS2013测试程序
- Java到底是值传递还是引用传递呢?(只有值传递)
- 上海Uber优步司机奖励政策(1月18日~1月24日)
- NOIP2008 ISBN号码(一桶水)【A005】
- 开窗函数之OVER子句、PARTITION BY 子句
- [回顾]清华申请退学博士作品:完全用Linux工作
- (Android图片内存优化)Picasso加载图片 教程。。详细版
- NUC505 USB存在的问题
- 169_线段树实现RMQ
- C#索引器的详细用法
- [leetcode]Spiral Matrix
- 数据中心两种常用流量模型运用mininet的实现
- SQL 查找 45道练习题
- c# 两个数组比较,将重复部分去掉,返回不重复部分