题面和数据 : 二次联通门
难度 : 普及-
/* T1 求多项式结果的后k位,由于k<=8, 所以不必考虑高精了,直接把多项式一遍算, 一边取模,注意用快速幂,最后补0输出即可。 复杂度 O (n log b) */ #include <cstdio> #define Max 100090 void read (int &now) { register char word = getchar (); bool temp = false; for (now = 0; word < ‘0‘ || word > ‘9‘; word = getchar ()) if (word == ‘-‘) temp = true; for (; word >= ‘0‘ && word <= ‘9‘; now = now * 10 + word - ‘0‘, word = getchar ()); if (temp) now = -now; } int Mod = 1; int N, K, X; int a[Max], b[Max]; long long Fast_Pow (long long x, long long p) { register long long res = 1; for (; p; p >>= 1) { if (p & 1) res = res * x % Mod; x = x % Mod * x % Mod; } return res; } #define Judge long long Answer; int number[Max / 1000]; int main (int argc, char *argv[]) { #ifdef Judge freopen ("digits.in", "r", stdin); freopen ("digits.out", "w", stdout); #endif read (N); read (K); for (int i = 1; i <= N; i ++) { read (a[i]); read (b[i]); } for (int i = K, res = 10; i; i >>= 1) { if (i & 1) Mod = Mod * res; res *= res; } read (X); for (int i = 1; i <= N; i ++) Answer = (Answer + (a[i] * Fast_Pow (X, b[i]) % Mod)) % Mod; int Count = 0; for (; Answer > 0; number[++ Count] = Answer % 10, Answer /= 10); for (int i = Count; i < K; i ++, printf ("0\n")); for (; Count >= 1; printf ("%d\n", number[Count --])); return 0; }
/* T2 把多项式左边的负项移到右边, O(N^3)预处理出右边的结果,用一个桶记录下来, 后O(N^3)枚举左边的结果, 加减就好了 复杂度O(N^3) */ #include <cstdio> #define Max 60000002 #define N 6 void read (int &now) { register char word = getchar (); bool temp = false; for (now = 0; word < ‘0‘ || word > ‘9‘; word = getchar ()) if (word == ‘-‘) temp = true; for (; word >= ‘0‘ && word <= ‘9‘; now = now * 10 + word - ‘0‘, word = getchar ()); if (temp) now = -now; } #define Judge int K; short z_count[Max]; short f_count[Max]; int a1, a2, a3, a4, a5, a6; int main (int argc, char *argv[]) { #ifdef Judge freopen ("equation.in", "r", stdin); freopen ("equation.out", "w", stdout); #endif read (K); read (a1); read (a2); read (a3); read (a4); read (a5); read (a6); register int x; for (register int i = 1, j, k; i <= K; i ++) for (j = 1; j <= K; j ++) for (k = 1; k <= K; k ++) { x = a2 * i + a4 * j + a6 * k; if (x >= 0) z_count[x] ++; else f_count[-x] ++; } int Answer = 0; for (register int i = 1, j, k; i <= K; i ++) for (j = 1; j <= K; j ++) for (k = 1; k <= K; k ++) { x = a1 * i + a3 * j + a5 * k; if (x >= 0) Answer += z_count[x]; else Answer += f_count[-x]; } printf ("%d", Answer); return 0; }
/* T3 由于k>=n,所以一天最多走一条边, 则问题转化为了求最小瓶颈生成树的裸题。。。。 若一直到最后起点与终点都不联通,那么则无解 复杂度 O(M logM + M) = O (M log M) */ #include <algorithm> #include <cstdio> #define Max 8000 void read (int &now) { register char word = getchar (); for (now = 0; word < ‘0‘ || word > ‘9‘; word = getchar ()); for (; word >= ‘0‘ && word <= ‘9‘; now = now * 10 + word - ‘0‘, word = getchar ()); } inline int max (int a, int b) { return a > b ? a : b; } struct Edge { int from; int to; int dis; bool operator < (const Edge &now) const { return this->dis < now.dis; } }; class Unio_Find_Set { private : int father[Max]; public : void Prepare (int N) { for (int i = 1; i <= N; i ++) father[i] = i; } int Find (int x) { return father[x] == x ? x : father[x] = Find (father[x]); } inline void Unio (int a, int b) { father[a] = b; } }; Unio_Find_Set Ufs; int N, M, K; Edge edge[Max * 30]; #define Judge int main (int argc, char *argv[]) { #ifdef Judge freopen ("graph.in", "r", stdin); freopen ("graph.out", "w", stdout); #endif read (N); read (M); read (K); for (int i = 1; i <= M; i ++) { read (edge[i].from); read (edge[i].to); read (edge[i].dis); } Ufs.Prepare (N); std :: sort (edge + 1, edge + 1 + M); int Count = 0; for (register int i = 1, x, y; i <= M; i ++) { x = Ufs.Find (edge[i].from); y = Ufs.Find (edge[i].to); if (x != y) { Ufs.Unio (x, y); Count ++; } if (Ufs.Find (1) == Ufs.Find (N)) { printf ("%d", edge[i].dis); return 0; } if (Count == N - 1) break; } printf ("-1"); return 0; }
时间: 2024-10-31 16:28:18