标签:style c class blog code tar
A. Scenic Popularity
http://acm.hdu.edu.cn/showproblem.php?pid=4831
思路:景点区会控制休息区的Hot值,我们建立休息区到它最近的景点区的关系,注意处理冲突。
查询和修改都暴力进行,预处理关系,从左到右,然后从右到左遍历一遍即可,更新时候,从被修改的p位置,向两边,与p有关的休息区进行更新。总的时间复杂度O(T*n*K),10^8左右,不到1s可以解决。
const int maxn = 10000; const int maxh = 100000; struct node { int pos; //位置 int hot; //hot值 bool isRest; //是否是休息区 int control[2]; //休息区所属的风景区下标 }elem[maxn]; void run() { int t, n, p, v; scanf("%d", &t); FOR(Cas, 1, t) { scanf("%d", &n); FOR(i, 0, n - 1) { scanf("%d%d", &p,&v); elem[i].pos = p; elem[i].hot = v; elem[i].isRest = (v == 0) ? true : false; memset(elem[i].control, -1, sizeof(elem[i].control)); } //Left->Right int lMark = -1; FOR(i, 0, n - 1) { if (!elem[i].isRest) { lMark = i; } else if (lMark != -1 && elem[i].isRest) { elem[i].control[0] = lMark; elem[i].hot = elem[lMark].hot; } } //Right->Left int rMark = -1; FORD(i, n-1, 0) { if (!elem[i].isRest) { rMark = i; } else if (rMark != -1 && elem[i].isRest) { if (elem[i].control[0] == -1) {//未被控制的休息点 elem[i].control[0] = rMark; elem[i].hot = elem[rMark].hot; } else { int lMark = elem[i].control[0]; int flag = abs(elem[rMark].pos - elem[i].pos) - abs(elem[lMark].pos - elem[i].pos);//flag 1:L -1:R 0:E if (flag != 0) { elem[i].control[0] = flag > 0 ? lMark : rMark; elem[i].control[1] = -1; elem[i].hot = elem[elem[i].control[0]].hot; } else { elem[i].control[0] = lMark; elem[i].control[1] = rMark; elem[i].hot = max(elem[lMark].hot, elem[rMark].hot); } } } } //query int query; scanf("%d", &query); printf("Case #%d:\n", Cas); FOR(i, 1, query) { char ch[10]; scanf("%s", ch); if (!strcmp(ch, "Q")) { scanf("%d", &v); int ans = 0; FOR(idx, 0, n - 1) { if (elem[idx].hot <= v) ans++; } printf("%d\n", ans); } else { scanf("%d%d", &p, &v); elem[p].hot = v; int idx; //Left update for (idx = p - 1; idx >= 0 && elem[idx].isRest && ((elem[idx].control[0] == p) || (elem[idx].control[1] == p)); idx--) { elem[idx].hot = elem[elem[idx].control[0]].hot; if (elem[idx].control[1] != -1) { elem[idx].hot = max(elem[idx].hot, elem[elem[idx].control[1]].hot); } } //Right update for (idx = p + 1; idx < n && elem[idx].isRest && ((elem[idx].control[0] == p) || (elem[idx].control[1] == p)); idx++) { elem[idx].hot = elem[elem[idx].control[0]].hot; if (elem[idx].control[1] != -1) { elem[idx].hot = max(elem[idx].hot, elem[elem[idx].control[1]].hot); } } } } } }
B.
C.
D. JZP Set
http://acm.hdu.edu.cn/showproblem.php?pid=4834
思路:定义要求的函数为g(n), 枚举前几项,然后OEIS,找到 http://oeis.org/A124197,
我们可以得到,g(n) = n + 1 + f(1) + f(2) + ... + f(n-1)
那么f(n) = f(n-1) + h(n);
h(n)是整数n的奇数因子的个数,那么
h(n) = d(n),n为奇数
h(n) = d(n) - d(n/2),n为偶数
d(n)是整数n的因子个数。
使用打表,将整数n进行质因子分解,2^p1*3^p2*5*p3....,n的因子个数为(p1+1)(p2+1)(...),这里打一个素数表然后分解
得到d(n),就可以向上迭代得到g(n),n数据范围为10^7,最后结果注意要是64bit。注意因子分解时候进行时间优化,以及整体的空间优化。
const int maxn = 10000000; int d[maxn + 5]; int64 f, g[maxn + 5]; int prime[maxn/5]; bool isPrime[maxn + 5]; void run() { int i, j; isPrime[1] = isPrime[1] = 1; for (i = 2; i <= maxn; ++i) { if (!isPrime[i]) { for (j = i + i; j <= maxn; j+=i) { isPrime[j] = 1; } } } int cnt = 0; for (i = 2; i <= maxn; i++) { if (!isPrime[i]) prime[cnt++] = i; } d[1] = 1; for (i = 2; i <= maxn; ++i) { int val = i, ans = 1; if (!isPrime[i]) d[i] = 2; else { for (j = 0; j < cnt; ++j) { if (prime[j] > val) break; int tmp = 0; while (val % prime[j] == 0) { tmp++; val /= prime[j]; } ans *= (tmp + 1); if (!isPrime[val]) { ans <<= 1; break; } } d[i] = ans; } } f = 1; g[1] = 2; for (i = 2; i <= maxn; ++i) { g[i] = g[i - 1] + f + 1; f += ((i & 0x01) ? d[i] : (d[i] - d[i >> 1])); } int t, e; scanf("%d", &t); for (int nt = 1; nt <= t; ++nt) { scanf("%d", &e); printf("Case #%d:\n%I64d\n", nt, g[e]); } }
标签:style c class blog code tar
原文地址:http://www.cnblogs.com/tiny656/p/3753039.html