今天目标10题达成。ε=ε=ε=(~ ̄▽ ̄)~ 。
总结一下今天:
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 2e3 + 10; const int M = N * N; int head[N], nt[M], to[M], tot; void add(int u, int v){ to[tot] = v; nt[tot] = head[u]; head[u] = tot++; } int belong[N], dfn[N], low[N], now_time, scc_cnt; stack<int> s; void dfs(int u){ dfn[u] = low[u] = ++now_time; s.push(u); for(int i = head[u]; ~i; i = nt[i]){ if(!dfn[to[i]]) dfs(to[i]); if(!belong[to[i]]) low[u] = min(low[u], low[to[i]]); } if(dfn[u] == low[u]){ ++scc_cnt; int now; while(1){ now = s.top(); s.pop(); belong[now] = scc_cnt; if(now == u) break; } } } void scc(int n){ now_time = scc_cnt = 0; for(int i = 1; i <= n; ++i) if(!belong[i]) dfs(i); } int main(){ memset(head, -1, sizeof(head)); int n, t; scanf("%d", &n); for(int i = 1; i <= n; ++i){ for(int j = 1; j <= n; ++j){ scanf("%d", &t); if(t) add(i, j); } } scc(n); // cout << "?" << endl; if(scc_cnt ^ 1) puts("NO"); else puts("YES"); return 0; }
*重点是将dp[i][j]看作 i -> j 之间存在有一条边, 如果dp[i][j] 本来没有边, 那么会通过别的点走过来。
所以跑一边scc之后,判断一下是不是一个强连通的点。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; char s[N]; string str[N]; LL dp[15], base[15]; void solve(string & sstr){ int m = sstr[0] - '0'; int len = sstr.size(); LL tmp_base = 1; LL tmp_yu = 0; for(int i = 3; i < len; ++i){ int id = sstr[i] - '0'; tmp_base = (tmp_base * base[id]) % mod; tmp_yu = (tmp_yu * base[id] + dp[id]) % mod; } dp[m] = tmp_yu, base[m] = tmp_base; // cout << m << ' ' << dp[m] << ' ' << base[m] << endl; } int main(){ scanf("%s", s+1); int n; scanf("%d", &n); for(int i = 0; i < 10; ++i) dp[i] = i, base[i] = 10; for(int i = 1; i <= n; ++i){ cin >> str[i]; } for(int i = n; i >= 1; --i){ solve(str[i]); } int m = strlen(s+1); LL ans = 0; for(int i = 1; i <= m; ++i){ int id = s[i] - '0'; ans = (ans * base[id] + dp[id]) % mod; } cout << ans << endl; return 0; }
* 将每个0~9的字符所对应的值和长度表现出来就好了。
3. Sereja and the Arrangement of Numbers
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; int n, m; int a[N], b[N]; LL dp[N]; int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= m; ++i){ scanf("%d%d", &a[i], &b[i]); if(i&1) dp[i] = 1 + i * (i - 1ll) / 2; else dp[i] = 1 + i * (i-1ll)/2 + i/2 - 1; } int k = m; while(dp[k] > n) --k; sort(b+1, b+1+m, greater<int>()); LL ans = 0; for(int i = 1; i <= k; ++i) ans += b[i]; cout << ans << endl; return 0; }
* 重点是将点和拓扑图挂钩。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; int u[N], v[N], c[N]; vector<int> vc[N]; int n, m; int ind[N], top[N]; bool check(int mid){ for(int i = 1; i <= n; ++i){ vc[i].clear(); ind[i] = 0; } for(int i = 1; i <= m; ++i){ if(c[i] > mid){ vc[u[i]].pb(v[i]); ind[v[i]]++; } } queue<int> q; int m = 0; for(int i = 1; i <= n; ++i){ if(!ind[i]) q.push(i); } while(!q.empty()){ int x = q.front(); q.pop(); top[x] = ++m; for(int v : vc[x]){ ind[v]--; if(!ind[v]) q.push(v); } } for(int i = 1; i <= n; ++i){ if(ind[i]) return false; } return true; } vector<int> ans; int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= m; ++i) scanf("%d%d%d", &u[i], &v[i], &c[i]); int L = 0, R = 1e9 + 100; while(L <= R){ int mid = L+R >> 1; if(!check(mid)) L = mid + 1; else R = mid - 1; } check(L); int tt = 0; for(int i = 1; i <= m; ++i){ if(c[i] <= L) { if(top[u[i]] > top[v[i]]){ ans.pb(i); } } } printf("%d %d ", L, ans.size()); for(int id : ans){ printf("%d ", id); } return 0; }
* 还是题目没读仔细, 读仔细应该能想到二分。
* 然后不知道 二分完之后,怎么确定小的边。 -> 用top去维护出边的方向, 这样就会存在环了。
其他:
1. 读题还是有点问题, 不知道怎么说, 还是会漏掉比较重要的条件。
2. 空间还是有时候没注意, 或者说下意识的就以为够了。
3. 思路在自己想的时候想好了, 然后写的忘了, 然后补完之后,特殊的小情况忘了改。。。。