A - Infinite Sequence CodeForces - 622A
题目大意:给你一个这样的数列1,1,2,1,2,3,1,2,3,4,1,2,3,4,5.。。。就是从1~n排列(n++).最后问你第n个位置是什么数字。
思路:如果你花点时间列数列的话会发现,1~n的最后一位对应的位置是1~n的和,那我们就大胆使用二分进行搜索这位数。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<set> #include<string> #include<vector> #include<ctime> #include<stack> #include<fstream> #include<iomanip> #include<deque> using namespace std; typedef long long ll; typedef unsigned long long ull; #define mm(a,b) memset(a,b,sizeof(a)) #define maxn 300 #define len 150000000+5 #define inf 0x3f3f3f3f int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a%b); } int main() { ll n; scanf("%lld", &n); ll l = 1, r = 1e8, mid; while (l <= r) { mid = (l + r) / 2; if ((mid + 1)*mid / 2 >= n && (mid - 1)*mid / 2 < n) break; else if ((mid + 1)*mid / 2 < n) l = mid + 1; else r = mid - 1; } ll maxx = (mid + 1)*mid / 2; ll ans = mid - (maxx - n); printf("%lld\n", ans); return 0; }
B - Optimal Number Permutation CodeForces - 622D
题意:给你一个数组,长度为2*n,出现的数字是1~n(每个数字出现两遍)。两个相同数字之间定义了距离di=xi-yi(xi>yi),最后问如何构造这个数组的序列,使得求和.值最小。
思路:看到这样的题先不要着急,想列一下式子,我们就可以发现,你可以构造出一个s=0的数列。
例如:
n=1 1
n=2 1 1 2 2
n=3 1 3 1 2 2 3
n=4 1 2 4 2 1 3 3 4
数字从1~n-1开始排序,n因为怎么样都是0,可以插空排。然后如果这个数字是奇数,我们从左边开始放,偶数从右边开始放。排放就按使得该数(di+i-n)=0的位置排(我也不知道为什么不会覆盖)。然后最后放n。
有个坑点(我自己的),总是数组开小,给你n<=500000,你要开两倍啊。TAT
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<set> #include<string> #include<vector> #include<ctime> #include<stack> #include<fstream> #include<iomanip> #include<deque> using namespace std; typedef long long ll; typedef unsigned long long ull; #define mm(a,b) memset(a,b,sizeof(a)) #define maxn 2*500000+50 #define len 150000000+5 #define inf 0x3f3f3f3f int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a%b); } int ans[maxn]; int main() { int n; memset(ans, 0, sizeof(ans)); scanf("%d", &n); int left = 1, right = n + 1; for (int i = 1; i <= n - 1; i++) { if (i % 2 == 1) { ans[left] = i; ans[left + n - i] = i; left++; } else { ans[right] = i; ans[right + n - i] = i; right++; } } for (int i = 1; i <= 2 * n; i++) { if (!ans[i]) ans[i] = n; } for (int i = 1; i <= 2 * n; i++) { printf("%d ", ans[i]); } printf("\n"); return 0; }
C - Not Equal on a Segment CodeForces - 622C
题意:给你n个数字和m个询问。询问格式:l,r,x,输出在l~r之间a[i]<>x的下标i。
思路:在读入数组的时候就需要将和这个数不相等的位置找到啦,往后面找。因为要么区间的第一个数字和x相等,要么不相等。不相等直接输出当前的位置i,相等就需要往后找啦。
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<functional> using namespace std; const int maxn = 2e5 + 50; int a[maxn], f[maxn]; int main() { int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) { if (a[i] != a[i + 1]) f[i] = i + 1; else { int pos = i; for (; a[i] == a[i + 1];) i++; for (int j = pos; j <= i; j++) f[j] = i + 1; } } while (m--) { int l, r, x; scanf("%d %d %d", &l, &r, &x); int flag = 0; for (int i = l; i <= r; i++) { if (a[i] == x) { if (f[i] > r || f[i] == 0) break; printf("%d\n", f[i]); flag = 1; break; } else { printf("%d\n", i); flag = 1; break; } } if (!flag) printf("-1\n"); } return 0; }
D - Ants in Leaves CodeForces - 622E
题意:给你一棵树,一只小蚂蚁在一个叶节点上,他们想回到根节点1,他们可以往自己的父节点爬行,爬行一段花费1个时间点。有个要求是,除了root可以容纳一个ant以外,其它节点只能容纳一只ant,所以如果一个ant在父节点。他的兄弟节点就需要等待一定的时间。问:所有蚂蚁回到叶节点的最小时间是多少?
思路:实验室的巨巨说,可以逆着想,可以假设所有蚂蚁都在根节点上,那么就是所有蚂蚁到叶节点的最短时间。这题就是需要建树,然后dfs一下,给每个子节点深度赋值。
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<functional> using namespace std; const int maxn = 5e5 + 50; int head[maxn * 2], num, cnt, dp[maxn], d[maxn]; struct node { int to, next, w; }e[maxn*2]; void init() { num = 0; memset(head, -1, sizeof(head)); } void add(int u, int v) { e[num].to = v; e[num].next = head[u]; head[u] = num++; } void dfs(int u, int fa, int depth) { int flag = 0; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; flag = 1; dfs(v, u, depth + 1); } if (!flag) d[cnt++] = depth; } int main() { init(); int n, u, v, ans = 0; scanf("%d", &n); for (int i = 0; i < n - 1; i++) { scanf("%d %d", &u, &v); add(u, v); add(v, u); } for (int i = head[1]; ~i; i = e[i].next) { int v = e[i].to; cnt = 0; dfs(v, 1, 1); sort(d, d + cnt); for (int j = 1; j < cnt; j++) d[j] = max(d[j - 1] + 1, d[j]); ans = max(ans, d[cnt - 1]); } printf("%d\n", ans); return 0; }
E - The Sum of the k-th Powers CodeForces - 622F
题意: % 109 + 7
思路:还不会。