11.7模拟赛
T1找循环节
循环节的大小一定在49之内(7*7)
读入int,挂成55
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> using namespace std; const int N = 1000000; #define LL long long LL f[N]; LL n, A, B, js, bi1, bi2; inline LL read(){ LL x = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x; }int main() { freopen("attack.in", "r", stdin); freopen("attack.out", "w", stdout); A = read(); B = read(); n = read(); bi1 = (A + B) % 7; bi2 = (A * bi1 + B) % 7; f[1] = f[2] = 1; f[3] = bi1; f[4] = bi2; for(int i = 5; ; i ++){ f[i] = (A * f[i - 1] + B * f[i - 2]) % 7; if(f[i] == bi2 && f[i - 1] == bi1){ js = i; break; } } for(int i = 1; i <= js - 3; i ++) f[i] = f[i + 2]; js -= 4; n -= 2; LL ans = n % js; if(!ans) printf("%lld", f[js] % 7); else printf("%lld", f[ans] % 7); return 0; } /* 455322504 473147848 236471319 */
T2打表找规律
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int T; double n,m; inline int read() { int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int main() { freopen("fseq.in","r",stdin); freopen("fseq.out","w",stdout); T=read(); while(T--) { n=read();m=read(); if(n<m) {puts("0.000000");continue;} double _1=n-m+1,_2=n+1; printf("%.6lf\n",_1/_2); } return 0; }
T3
/* 套路题,没营养 Tarjan缩点 求出缩完点后树的直径 对于每个点,若在最长链上就直接对两个端点取max 否则就一直往上跳,累加边权,直到跳到最长链上 然后做上一种情况的操作就好了 */ #include <cstdio> #include <iostream> #define rg register inline void read (int &n) { rg char c = getchar (); for (n = 0; !isdigit (c); c = getchar ()); for (; isdigit (c); n = n * 10 + c - '0', c = getchar ()); } #define Max 40008 int _v[Max * 20], _n[Max * 20], list[Max * 20], EC = 1, _d[Max * 20]; int N; inline void In (int u, int v, int d) { _v[++ EC] = v, _n[EC] = list[u], list[u] = EC, _d[EC] = d; } int t, sk[Max], DC, SC; int dfn[Max], low[Max], scc[Max]; inline void cmin (int &a, int b) { if (b < a) a = b; } void Dfs (int n, int l) { sk[++ t] = n; dfn[n] = low[n] = ++ DC; for (rg int i = list[n], v; i; i = _n[i]) if (i != l && i != (l ^ 1)) { if (!dfn[v = _v[i]]) Dfs (v, i), cmin (low[n], low[v]); else if (!scc[v]) cmin (low[n], dfn[v]); } if (low[n] == dfn[n]) { ++ SC; for (int r = n + 1; t && r != n; -- t) r = sk[t], scc[r] = SC; } } int ev[Max * 20], en[Max * 20], el[Max * 10], ec, ed[Max * 20]; inline void _In (int u, int v, int d) { ev[++ ec] = v, en[ec] = el[u], el[u] = ec, ed[ec] = d; ev[++ ec] = u, en[ec] = el[v], el[v] = ec, ed[ec] = d; } bool Find (int x, int y) { for (rg int i = el[x]; i; i = en[i]) if (ev[i] == y) return true; return false; } void Tarjan () { rg int i; for (i = 1; i <= N; ++ i) if (!dfn[i]) Dfs (i, 0); for (int n = 1; n <= N; ++ n) for (i = list[n]; i; i = _n[i]) if (scc[n] != scc[_v[i]]) if (!Find (scc[n], scc[_v[i]])) { _In (scc[n], scc[_v[i]], _d[i]); } } int Answer[Max]; int dis1[Max], dis2[Max], pos1, pos2, Max1, Max2, pre[Max]; void Gc1 (int n, int F) { for (rg int i = el[n], v; i; i = en[i]) if ((v = ev[i]) != F) dis1[v] = dis1[n] + ed[i], Gc1 (v, n); if (dis1[n] > Max1) Max1 = dis1[n], pos1 = n; } int f[Max]; void Gc2 (int n, int F) { f[n] = F; for (rg int i = el[n], v; i; i = en[i]) if ((v = ev[i]) != F) dis2[v] = dis2[n] + ed[i], Gc2 (v, n), pre[v] = n; if (dis2[n] > Max2) Max2 = dis2[n], pos2 = n; } bool isc[Max]; inline int max (int a, int b) { return a > b ? a : b; } void GetAnswer () { Gc1 (1, 0), Gc2 (pos1, 0); rg int i; for (i = pos2; i; i = pre[i]) isc[i] = true; rg int n; int res = 0, j; for (i = 1; i <= SC; ++ i) { res = 0; for (n = i; !isc[n] && n; n = f[n]) { for (j = el[n]; j; j = en[j]) if (ev[j] == f[n]) { res += ed[j]; break; } } res += max (dis2[n], Max2 - dis2[n]); Answer[i] = res; } for (i = 1; i <= N; ++ i) printf ("%d\n", Answer[scc[i]]); } int main (int argc, char *argv[]) { int x, y, M, z; read (N), read (M); for (rg int i = 1; i <= M; ++ i) read (x), read (y), read (z), In (x, y, z), In (y, x, z); Tarjan (); GetAnswer (); return 0; }
更好理解的思路:
首先缩点
然后找出树的直径
对于在树上的点,输出该点到直径两端点的较大值
否则输出该点到直径的距离+该点所在链与直径的交点处到直径两个端点的较大值