2140: 稳定婚姻
1 /* 2 求联通分量。 3 */ 4 #include<bits/stdc++.h> 5 using namespace std; 6 typedef long long LL; 7 8 inline int read() { 9 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 10 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 11 } 12 13 const int N = 10010; 14 int head[N],nxt[50010],to[50010]; 15 int dfn[N],low[N],st[N],bel[N]; 16 int Enum,TimeIndex,NumberPeople,BlockIndex,top; 17 bool vis[N]; 18 19 20 map<string,int> p; 21 22 struct Couple{ 23 string a,b; 24 }c[N]; 25 26 inline void add_edge(int u,int v) { 27 ++Enum;to[Enum] = v, nxt[Enum] = head[u],head[u] = Enum; 28 } 29 30 void tarjan(int u) { 31 dfn[u] = low[u] = ++TimeIndex; 32 st[++top] = u; // -- 33 vis[u] = true; // -- 34 for (int i=head[u]; i; i=nxt[i]) { 35 int v = to[i]; 36 if (!dfn[v]) { 37 tarjan(v); 38 low[u] = min(low[u],low[v]); 39 } 40 else if (vis[v]) low[u] = min(low[u],dfn[v]); 41 } 42 if (dfn[u] == low[u]) { 43 ++BlockIndex; 44 do { 45 bel[st[top]] = BlockIndex; 46 vis[st[top]] = false; // -- 47 top--; 48 } while (st[top+1] != u); 49 } 50 } 51 52 int main() { 53 int n = read(); 54 string a,b; 55 int tot = 0; 56 for (int i=1; i<=n; ++i) { 57 cin >> c[i].a >> c[i].b; 58 p[c[i].a] = ++NumberPeople; 59 p[c[i].b] = ++NumberPeople; 60 add_edge(NumberPeople-1,NumberPeople); 61 } 62 int m = read(); 63 for (int i=1; i<=m; ++i) { 64 cin >> a >> b; 65 add_edge(p[b],p[a]); 66 } 67 for (int i=1; i<=NumberPeople; ++i) { // -- i<=n 68 if (!dfn[i]) tarjan(i); 69 } 70 for (int i=1; i<=n; ++i) { 71 if (bel[p[c[i].a]] == bel[p[c[i].b]]) puts("Unsafe"); 72 else puts("Safe"); 73 } 74 return 0; 75 }
2783: [JLOI2012]树
1 /* 2 读好题目。 3 所有路径都是 深度小的->深度大的。 4 所以,dfs一遍。 5 */ 6 #include<bits/stdc++.h> 7 using namespace std; 8 typedef long long LL; 9 10 inline int read() { 11 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 12 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 13 } 14 15 const int N = 100005; 16 int head[N],nxt[N<<1],to[N<<1],Enum; 17 int w[N],S,Ans; 18 map<int,int> cnt; 19 20 inline void add_edge(int u,int v) { 21 ++Enum;to[Enum] = v, nxt[Enum] = head[u],head[u] = Enum; 22 } 23 24 void dfs(int u,int fa,int sum) { 25 if (cnt[sum - S]) Ans += cnt[sum - S]; 26 for (int i=head[u]; i; i=nxt[i]) { 27 int v = to[i]; 28 if (v == fa) continue; 29 cnt[sum+w[v]] ++; 30 dfs(v,u,sum+w[v]); 31 cnt[sum+w[v]] --; 32 } 33 } 34 35 int main() { 36 int n = read();S = read(); 37 for (int i=1; i<=n; ++i) w[i] = read(); 38 for (int i=1; i<n; ++i) { 39 int u = read(),v = read(); 40 add_edge(u,v);add_edge(v,u); 41 } 42 cnt[0] = 1;cnt[w[1]] = 1; 43 dfs(1,0,w[1]); 44 cout << Ans; 45 return 0; 46 }
2429: [HAOI2006]聪明的猴子
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 5 inline int read() { 6 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 7 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 8 } 9 10 const int N = 1010; 11 struct Edge{ 12 int u,v;double w; 13 Edge() {} 14 Edge(int a,int b,double c) {u = a, v = b, w = c;} // double c 15 bool operator < (const Edge &A) const { 16 return w < A.w; 17 } 18 }e[N*N]; 19 int x[N],y[N],fa[N],a[N],Enum; 20 21 int find(int x) { 22 if (x == fa[x]) return x; 23 return fa[x] = find(fa[x]); 24 } 25 int main() { 26 int n = read(); 27 for (int i=1; i<=n; ++i) a[i] = read(); 28 sort(a+1,a+n+1); 29 int m = read(); 30 for (int i=1; i<=m; ++i) 31 x[i] = read(),y[i] = read(); 32 for (int i=1; i<=m; ++i) 33 for (int j=i+1; j<=m; ++j) { 34 double w = sqrt(1.0*(x[i]-x[j])*(x[i]-x[j])+1.0*(y[i]-y[j])*(y[i]-y[j])); 35 e[++Enum] = Edge(i,j,w); 36 } 37 sort(e+1,e+Enum+1); 38 for (int i=1; i<=m; ++i) fa[i] = i; //-- i<=m 39 int cnt = 0;double mx; 40 for (int i=1; i<=Enum; ++i) { 41 int u = find(e[i].u), v = find(e[i].v); 42 if (u != v) { 43 fa[u] = v; 44 cnt ++; 45 mx = e[i].w; 46 if (cnt == m - 1) break; // -- cnt=n-1 47 } 48 } 49 int Ans = 0; 50 for (int i=n; i>=1; --i) if (a[i] >= mx) Ans ++; //--居然反了。。 51 cout << Ans; 52 return 0; 53 }
2946: [Poi2000]公共串
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 5 inline int read() { 6 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 7 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 8 } 9 10 const int N = 200010; 11 12 struct SuffixAutomaton{ 13 int Last, Index, res, cur, fa[N], trans[N][26], len[N]; 14 SuffixAutomaton() {Last = Index = cur = 1; res = 0;} 15 void extend(int c) { 16 int P = Last, NP = ++Index; 17 len[NP] = len[P] + 1; 18 for (; P&&!trans[P][c]; P=fa[P]) trans[P][c] = NP; 19 if (!P) fa[NP] = 1; 20 else { 21 int Q = trans[P][c]; 22 if (len[P] + 1 == len[Q]) fa[NP] = Q; 23 else { 24 int NQ = ++Index; 25 fa[NQ] = fa[Q]; 26 len[NQ] = len[P] + 1; 27 memcpy(trans[NQ], trans[Q], sizeof trans[Q]); 28 fa[Q] = NQ; 29 fa[NP] = NQ; 30 for (; P&&trans[P][c]==Q; P=fa[P]) trans[P][c] = NQ; 31 } 32 } 33 Last = NP; 34 } 35 int solve(int c) { 36 if (trans[cur][c]) {cur = trans[cur][c]; res++; return res;} 37 for (; cur&&!trans[cur][c]; cur=fa[cur]); 38 if (!cur) res = 0, cur = 1; 39 else res = len[cur] + 1, cur = trans[cur][c]; 40 return res; 41 } 42 }sam[9]; 43 44 char s[N]; 45 char str[N]; 46 47 int main() { 48 int n = 0,t = 0,len; 49 scanf("%s",str+1); 50 51 while (scanf("%s",s+1)!=EOF) { 52 len = strlen(s + 1); 53 for (int i=1; i<=len; ++i) 54 sam[t].extend(s[i] - 'a'); 55 t ++; 56 } 57 int ans = 0; 58 len = strlen(str+1); 59 for (int i=1; i<=len; ++i) { 60 int tmp = 1e9; 61 for (int j=0; j<t; ++j) 62 tmp = min(tmp, sam[j].solve(str[i] - 'a')); 63 ans = max(ans, tmp); 64 } 65 printf("%d",ans); 66 return 0; 67 }
3613: [Heoi2014]南园满地堆轻絮
1 /* 2 二分,每个数对应一个区间,每次取区间的最小值。 3 */ 4 #include<bits/stdc++.h> 5 using namespace std; 6 typedef long long LL; 7 8 inline int read() { 9 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 10 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 11 } 12 13 const int N = 5000100; 14 LL A[N], Sa, Sb, Sc, Sd, mod; 15 int n; 16 17 LL F(LL x) { 18 LL x2 = x * x % mod, x3 = x2 * x % mod; //--- 19 return (Sa * x3 % mod + Sb * x2 % mod + Sc * x % mod + Sd) % mod; 20 } 21 void init() { 22 Sa = read(), Sb = read(), Sc = read(), Sd = read(); A[1] = read(); mod = read(); 23 for (int i=2; i<=n; ++i) 24 A[i] = (F(A[i-1]) + F(A[i-2])) % mod; 25 } 26 27 bool check(LL x) { 28 LL last = A[1] - x; 29 for (int i=2; i<=n; ++i) { 30 if (A[i] >= last) { 31 last = max(A[i] - x, last); 32 } 33 else { 34 if (A[i] + x < last) return false; //--- 35 last = min(A[i] + x, last); 36 } 37 } 38 return true; 39 } 40 41 int main() { 42 43 n = read(); 44 init(); 45 46 LL L = 0, R = mod, ans; //--- 47 while (L <= R) { 48 LL mid = (L + R) >> 1; 49 if (check(mid)) ans = mid, R = mid - 1; 50 else L = mid + 1; 51 } 52 cout << ans; 53 54 return 0; 55 }
1 /* 2 找出最大的逆序对,然后答案是(mx-mn+1)/2 3 如果将最大的逆序对可以提升的一个平台,那么其他的逆序对也都可在这一平台。 4 5 下面摘自https://blog.csdn.net/vmurder/article/details/44096565 6 我们把所有逆序对点都搞到同一高度。 7 然后发现答案是距离最远的逆序对搞到一起的代价。 8 */ 9 #include<bits/stdc++.h> 10 using namespace std; 11 typedef long long LL; 12 13 inline int read() { 14 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 15 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 16 } 17 18 const int N = 5000100; 19 LL A[N], Sa, Sb, Sc, Sd, mod; 20 int n; 21 22 LL F(LL x) { 23 LL x2 = x * x % mod, x3 = x2 * x % mod; 24 return (Sa * x3 % mod + Sb * x2 % mod + Sc * x % mod + Sd) % mod; 25 } 26 void init() { 27 Sa = read(), Sb = read(), Sc = read(), Sd = read(); A[1] = read(); mod = read(); 28 for (int i=2; i<=n; ++i) 29 A[i] = (F(A[i-1]) + F(A[i-2])) % mod; 30 } 31 32 int main() { 33 34 n = read(); 35 init(); 36 37 LL Mx = -1e9, ans = 0; 38 for (int i=1; i<=n; ++i) { 39 if (A[i] >= Mx) Mx = A[i]; 40 else ans = max(ans, (Mx - A[i] + 1) / 2); 41 } 42 43 cout << ans; 44 45 return 0; 46 }
-----------