ACM's career is over
//The update prefix and (left interval prefix or right interval prefix + left interval and) t [cur]. Per = max (t [cur < < 1]. Sum = t [cur < < 1] < 1]. Sum; sum;; / / update prefix and (left interval prefix or right interval prefix + left interval prefix + left interval and) t [cur]. Per = max (t [cur < < 1]. Per, t [cur < 1] < 1]. Sum + T [cur < 1 < 1]. Per);;;;; / / update suffix and (same thing)
t [cur [cur or right interval prefix + left interval and) t [cur]; t [cur < < 1]. Sum = t [cur < 1]; sum = t [cur < 1]; sum + T [1]]. Suf = max (t [cur < < 1 | 1]. Suf, t [cur < < 1]. Suf + T [cur < < 1 | 1]. Sum);
/ / updates the maximum segment sum In the case of the left and right suffixes of T [cur, t] / (T, t] < cur (1); [t] / (T) < cur (1); [cur] / [t] < 1;
Accept C++14 (clang 4.0) 20ms:
/**
* @author Moe_ Sakiya sakiya@tun.moe
* @date 2019-07-23 13:19:44
*
*/
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
#define leftSon left,mid, Cur < < 1 define rightson mid + 1, right, cur < < 1| 1
const int maxn = 50005;
struct node {int sum; / / the interval of the current node and
int per; / / the maximum prefix of the current node and (the first sub segment and)
int suf; / / the maximum suffix of the current node and (the last sub segment and)
int con; //T [maxn < 2];;
; int n, q;;;; / / update update update update (void pushup (int cur) {/ / / / update interval and T [cur]. Sum = t [cur < < 1]. Sum = t [cur < < 1]. Sum + T [cur < < 1]. Sum;; / / update prefix and update prefix and (left or right prefix + left interval prefix + left interval and)
t [cur] (cur]. Per]. Sum = t [cur < < 1 < < 1]. Sum;;; / / update prefix update prefix and (left interval prefix or right prefix + left interval prefix + left interval and) t [cur]; t [cur]. Per]. Per / per]. Per / update prefix and (left interval prefix or right prefix + left interval prefix) = max (t [cur < 1]. Per, t [cur < 1]. Sum + T [cur < < 1]. Per); Update the suffix and (the same reason)
t [cur]. Suf = max (t [cur < 1 < 1241]; suf, t [cur < < 1 < 1]. Suf, t [cur < < 1 < 1]. Suf + T [cur < < 1 < 1 < 1]. Sum);;;; / / update largest sub segment and two situations
/ / 1. Separate in left and right interval
t [cur]. Con = max (t [cur < < < 1]. Con, t [cur < < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 < 1 <]. Con);
/ / 2. In the merged interval (left interval suffix + right interval prefix)
t [cur]. Con = max (t [cur]. Con, Void builtree (int left, int right, int cur) {int mid = (left + right) {int mid = (left + right) > > 1; < if if (left = = right) {scanf (% d ", & T [cur]. Sum); < T [t [cur]. Sum);
t [cur] / suf = t [cur]. Suf = t [cur] / suf = t [cur]. Suf = t [cur]. Saf = t [cur]. Saf = t [cur]. Saf = t [cur]. Saf = t [cur] / saf = t [cur] / saf = t [cur]. Saf = t [cur]. Saf = t = t [cur]. Saf = t per = t [cur]. Con = t [cur]. Sum;
return;
}
buildtree (leftson);
buildtree (rightson); Pushup (cur);
pushup (cur); (return;
return;
}
/ / modify void updatnode (int node, int value, int left, int right, int cur) {int mid = (left + right) > > 1;
if (left = = right) {t [cur]. Suf = t [cur]. Per = t [cur]. Get = t [cur]. Com = t [cur]. Com = t [cur]. Sum = value;
return;
(left = = right) {if (left = = right) {t [cur]. Suf = t [cur]; suf = t [cur]. Per = t = t [cur if (node < = mid)
updatenode (node, value, leftson); / / query the querysesection (int leftsection, int rightsection, int left, int right, int cur) {int mid = (left + right) > > 1; / / / / / / / / the current node is completely in the query interval
if (leftsection < = left & amp & amp; right < = right & amp; right < = right < = right, int right, int cur) {int mid = (left + right) > > 1;; / / the current node is completely in the query interval
if (leftsection < = left & amp; right < = right & amp; right < = right < = right < < if (leftsection < = left & amp; right < = right < = right < < if (leftsection < = left & amp & amp; right < = right < < if if if (leftsection < = left & amp; right < = right & amp htsection)
return t [cur]; / / the current node does not recurse downward in the query interval
if (mid < leftsection)
return querysection (leftsection, rightsection, rightson);
else if (rightsection < = mid)
return querysection (leftsection, rightsection, leftson); / / the current node takes the left and right subtrees in the query area to merge and solve (similar to the push up operation)
node retnode, leftnode, rightnode;
leftnode = querysection (leftsection, rightsection, leftson);
/ / merging interval result
retnode. Sum = leftnode. Sum + rightnode. Sum;
retNode.per = max(leftNode.per, leftNode.sum + rightNode.per);
retNode.suf = max(rightNode.suf, leftNode.suf + rightNode.sum);
retNode.con = max(leftNode.con, rightNode.con);
retNode.con = max(retNode.con, leftNode.suf + rightNode.per);
return retNode;
}
int main(void) {
ios::sync_ with_ stdio(false);
cin.tie(NULL);
int cmd, l, r;
scanf("%d", &n);
BuildTree(1, n, 1);
scanf("%d", &q);
for (int i = 0; i < q; i++) {
scanf("%d %d %d", &cmd, &l, &r);
switch (cmd) {
case 0:
UpdateNode(l, r, 1, n, 1);
break;
case 1:
printf("%d\n", QuerySection(l, r, 1, n, 1).con);
break;
}
}
return 0;
}
Accept G++ 530ms:
/**
* @author Moe_ Sakiya sakiya@tun.moe
* @date 2018-11-26 18:59:49
*
*/
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int maxN = 50005;
long long int arrPrime[maxN];
bool isPrime[maxN];
int cnt;
void calPrimes() {
memset(isPrime, 1, sizeof(isPrime));
cnt = 0;
isPrime[1] = false;
for (long long int i = 2; i < maxN; i++) {
if (isPrime[i] == true)
arrPrime[cnt++] = i;
for (int j = 0; j < cnt && i * arrPrime[j] < maxN; j++) {
isPrime[i * arrPrime[j]] = false;
if (i % arrPrime[j] == false)
break;
}
}
return;
}
long long int calNum(int n) {
long long int ret = 1;
int num;
for (int i = 0; i < cnt; i++) {
if (n % arrPrime[i] == 0) {
num = 1;
while (n % arrPrime[i] == 0 && n > 0) {
num++;
n /= arrPrime[i];
}
ret *= num;
}
}
return ret;
}
int main(void) {
ios::sync_ with_ stdio(false);
cin.tie(NULL);
long long int maxNum, maxCount;
int t, l, r;
calPrimes();
scanf("%d", &t);
while (t--) {
maxNum = 0;
maxCount = 0;
scanf("%d %d", &l, &r);
for (int i = l; i <= r; i++) {
long long int tmp = calNum(i);
if (tmp > maxCount) {
maxCount = tmp;
maxNum = i;
}
}
printf("Between %d and %d, %lld has a maximum of %lld divisors.\n", l, r, maxNum, maxCount);
}
return 0;
}
If the value of cur-1 (cur-1) is used, then the value of cur-1 (cur-1) is used
Reference: Joseph Galante: Generalized Cantor Expansions
Accept G++ 202ms 4992kB:
/**
* @author Moe_ Sakiya sakiya@tun.moe
* @date 2018-11-14 18:46:28
*
*/
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define leftSon left,mid,curr<<1
#define rightSon mid+1,right, curr<<1|1
using namespace std;
const int maxN = 50005;
struct DisNode
{
int l, r;
} disArr[maxN];
vector<int> vet[maxN];
int segTree[maxN << 2];
int lazyTag[maxN << 2];
int fatherArr[maxN];
int discnt;
inline void DFS(int id) {
disArr[id].l = discnt++;
for (int i = 0; i < (int)vet[id].size(); i++)
DFS(vet[id][i]);
disArr[id].r = discnt - 1;
return;
}
void pushDown(int curr) {
if (lazyTag[curr] != -1) {
lazyTag[curr << 1] = lazyTag[curr];
lazyTag[curr << 1 | 1] = lazyTag[curr];
segTree[curr << 1] = lazyTag[curr];
segTree[curr << 1 | 1] = lazyTag[curr];
lazyTag[curr] = -1;
}
return;
}
void buildTree(int left, int right, int curr) {
int mid = (left + right) >> 1;
if (left == right) {
segTree[curr] = -1;
return;
}
buildTree(leftSon);
buildTree(rightSon);
return;
}
void updateSection(int leftSection, int rightSection, int val, int left, int right, int curr) {
int mid = (left + right) >> 1;
if (leftSection <= left && right <= rightSection) {
lazyTag[curr] = val;
return;
}
pushDown(curr);
if (leftSection <= mid)
updateSection(leftSection, rightSection, val, leftSon);
if (rightSection > mid)
updateSection(leftSection, rightSection, val, rightSon);
return;
}
int queryNode(int node, int left, int right, int curr) {
int mid = (left + right) >> 1;
if (left == right) {
if (lazyTag[curr] != -1)
segTree[curr] = lazyTag[curr];
return segTree[curr];
}
pushDown(curr);
if (node <= mid)
return queryNode(node, leftSon);
else
return queryNode(node, rightSon);
}
int main(void) {
ios::sync_ with_ stdio(false);
cin.tie(NULL);
int t, n, m, arg0, arg1, u, v;
char ch[10];
scanf("%d", &t);
for (int kase = 1; kase <= t; kase++) {
// INIT
discnt = 1;
memset(fatherArr, 0, sizeof(fatherArr));
memset(vet, 0, sizeof(vet));
memset(lazyTag, -1, sizeof(lazyTag));
// DataIn
printf("Case #%d:\n", kase);
scanf("%d", &n);
for (int i = 0; i < n - 1; i++) {
scanf("%d %d", &u, &v);
fatherArr[u] = v;
vet[v].push_ back(u);
}
// Deal data & Build tree
for (int i = 1; i <= n; i++)
if (fatherArr[i] == 0)
DFS(i);
buildTree(1, n, 1);
scanf("%d", &m);
for (int i = 0; i < m; i++) {
// Query
scanf("%s", ch);
switch (ch[0]) {
case 'C':
scanf("%d", &arg0);
printf("%d\n", queryNode(disArr[arg0].l, 1, n, 1));
break;
case 'T':
scanf("%d %d", &arg0, &arg1);
updateSection(disArr[arg0].l, disArr[arg0].r, arg1, 1, n, 1);
break;
}
}
}
return 0;
}