我不想退役,一定要拿省一
奥利给
1. 堆
#include<bits/stdc++.h> using namespace std; #define rint register int int n; priority_queue< int, vector< int >, greater< int > > que; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } int main( void ){ n = read(); for( rint i = 1; i <= n; i++ ){ int temp; temp = read(); if( temp == 1 ) que.push( read() ); if( temp == 2 ) printf( "%d\n", que.top() ); if( temp == 3 ) que.pop(); } return 0; }
我觉得我的码风还挺好看的吧……
注意答案的换行
2. 负环
竟然是一道蓝题……
跑\(spfa\),注意使用的是普通队列
更新一条边使用的点数达到\(n\)就说明他自己更新了自己,存在负环
多组数据注意清空\(head\)数组
输出记得粘贴复制,不要手打
注意题目所说连边方式
#include<bits/stdc++.h> using namespace std; #define rint register int int T, n, m, cnt; int head[2010], dis[2010], cnte[2010], vis[2010]; struct edge{ int nxt, to, val; }a[6010]; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } inline void addedge( int x, int y, int z ){ a[++cnt].nxt = head[x]; a[cnt].to = y; a[cnt].val = z; head[x] = cnt; } inline bool spfa( int x ){ memset( dis, 0x3f, sizeof( dis ) ); memset( cnte, 0, sizeof( cnte ) ); memset( vis, 0, sizeof( vis ) ); queue< int > que; que.push( x ); dis[x] = 0; vis[x] = 1; while( que.size() ){ int now = que.front(); que.pop(); vis[now] = 0; if( cnte[now] >= n ) return 0; for( rint i = head[now]; i; i = a[i].nxt ){ int v = a[i].to, w = a[i].val; if( dis[v] > dis[now] + w ){ dis[v] = dis[now] + w; if( !vis[v] ){ cnte[v]++; vis[v] = 1; que.push( v ); if( cnte[v] >= n ) return 0; } } } } return 1; } int main( void ){ T = read(); while( T-- ){ cnt = 0; memset( head, 0, sizeof( head ) ); n = read(); m = read(); for( rint i = 1; i <= m; i++ ){ int a, b, c; a = read(); b = read(); c = read(); addedge( a, b, c ); if( c >= 0 ) addedge( b, a, c ); } if( spfa( 1 ) ) printf( "N0\n" ); else printf( "YE5\n" ); } return 0; }
3. 并查集
疯狂写\(T\) \(22\)分钟
只因为我把\(i <= m\)写成\(i = m\)
草
记得初始化
#include<bits/stdc++.h> using namespace std; #define rint register int int n, m; int fa[10010]; inline int getf( int now ){ if( fa[now] == now ) return now; else return fa[now] = getf( fa[now] ); } inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } int main( void ){ n = read(); m = read(); for( rint i = 1; i <= n; i++ ) fa[i] = i; for( rint i = 1; i <= m; i++ ){ int x, y, z; x = read(); y = read(); z = read(); if( x == 1 ) fa[getf(z)] = getf(y); else if( getf(y) == getf(z) ) printf( "Y\n" ); else printf( "N\n" ); } return 0; }
4. 线性筛
记得是\(j\) % \(prime[i]==0\)
#include<bits/stdc++.h> using namespace std; #define rint register int int n, m, cnt; int vis[10000010], prime[3000010]; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } int main( void ){ n = read(); m = read(); vis[0] = vis[1] = 1; for( rint i = 2; i <= n; i++ ){ if( !vis[i] ) prime[++cnt] = i; for( rint j = 1; j <= cnt && prime[j] * i <= n; j++ ){ vis[i * prime[j]] = 1; if( i % prime[j] == 0 ) break ; } } for( rint i = 1; i <= m; i++ ){ int temp; temp = read(); if( !vis[temp] ) printf( "Yes\n" ); else printf( "No\n" ); } return 0; }
5. 快速幂
第三次写错……
下次一定不会\(QAQ\)
#include<bits/stdc++.h> using namespace std; #define rint register int #define ll long long ll b, p, k; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } inline ll qpow( int x, int y, int mod ){ if( y == 0 ) return 1; ll re = 1; while( y ){ if( y % 2 ) re = ( re * x ) % mod; y >>= 1; x = ( x * x ) % mod; } return re % mod; } int main( void ){ b = read(); p = read(); k = read(); printf( "%lld^%lld mod %lld=%lld", b, p, k, ( qpow( b % k, p, k ) % k ) ); return 0; }
6. 最小生成树
记得写对并查集
记得初始化并查集
#include<bits/stdc++.h> using namespace std; #define rint register int #define ll long long int n, m, cnt, cnt2; ll ans; int fa[5010]; struct edge{ int u, v, val; }a[200010]; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } inline bool cmp( edge a, edge b ){ return a.val < b.val; } inline int getf( int now ){ if( fa[now] == now ) return now; else return fa[now] = getf( fa[now] ); } int main( void ){ n = read(); m = read(); for( rint i = 1; i <= m; i++ ){ int u, v, w; u = read(); v = read(); w = read(); a[i].u = u, a[i].v = v, a[i].val = w; } sort( a + 1, a + 1 + m, cmp ); for( rint i = 1; i <= n; i++ ) fa[i] = i; for( rint i = 1; i <= m; i++ ){ if( cnt2 == n - 1 ) break ; if( getf( a[i].u ) == getf( a[i].v ) ) continue ; else { cnt2++; fa[getf( a[i].v )] = fa[a[i].u]; ans += a[i].val; } } if( cnt2 == n-1 ) printf( "%lld", ans ); else printf( "orz" ); return 0; }
7. 线段树
为什么先打的这个???
跟\(YKY\)竞速输了
(就差一点……
#include<bits/stdc++.h> using namespace std; #define rint register int #define ll long long int n, m; ll a[1000010]; struct node{ int left, right; ll pre, tag; }tree[4000010]; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } inline void build( ll now, ll l, ll r ){ tree[now].left = l, tree[now].right = r; if( l == r ){ tree[now].pre = a[l]; return ; } ll mid = l + r >> 1; build( now << 1, l, mid ); build( now << 1 | 1, mid + 1, r ); tree[now].pre = tree[now << 1].pre + tree[now << 1 | 1].pre; } inline void spread( ll now ){ if( tree[now].tag ){ tree[now << 1].pre += tree[now].tag * ( tree[now << 1].right - tree[now << 1].left + 1 ); tree[now << 1 | 1].pre += tree[now].tag * ( tree[now << 1 | 1].right - tree[now << 1 | 1].left + 1 ); tree[now << 1].tag += tree[now].tag; tree[now << 1 | 1].tag += tree[now].tag; tree[now].tag = 0; } } inline void update( ll now, ll l, ll r, ll val ){ if( l <= tree[now].left && r >= tree[now].right ){ tree[now].pre += ( tree[now].right - tree[now].left + 1 ) * val; tree[now].tag += val; return ; } spread( now ); ll mid = tree[now].left + tree[now].right >> 1; if( mid < r ) update( now << 1 | 1, l, r, val ); if( l <= mid ) update( now << 1, l, r, val ); tree[now].pre = tree[now << 1].pre + tree[now << 1 | 1].pre; } inline ll query( int now, int l, int r ){ ll ans = 0; if( l <= tree[now].left && r >= tree[now].right ){ return tree[now].pre; } spread( now ); ll mid = tree[now].left + tree[now].right >> 1; if( mid < r ) ans += query( now << 1 | 1, l, r ); if( l <= mid ) ans += query( now << 1, l, r ); return ans; } int main( void ){ n = read(); m = read(); for( rint i = 1; i <= n; i++ ){ a[i] = read(); } build( 1, 1, n ); for( rint i = 1; i <= m; i++ ){ int bok, x, y, k; bok = read(); if( bok == 1 ){ x = read(); y = read(); k = read(); update( 1, x, y, k ); } else { x = read(); y = read(); printf( "%lld\n", query( 1, x, y ) ); } } return 0; }
8. lca
为什么又打的这个?
因为我竞速又输了……
\(8\)说了,自闭去了
#include<bits/stdc++.h> using namespace std; #define rint register int int n, m, s, cnt; struct edge{ int nxt, to; }a[1000010]; int fa[500010], top[500010], siz[500010], dep[500010], son[500010], head[500010]; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } inline void addedge( int x, int y ){ a[++cnt].to = y; a[cnt].nxt = head[x]; head[x] = cnt; } inline void dfs( int now, int f, int d ){ dep[now] = d; fa[now] = f; siz[now] = 1; for( rint i = head[now]; i; i = a[i].nxt ){ int v = a[i].to; if( v == f ) continue ; dfs( v, now, d + 1 ); siz[now] += siz[v]; if( siz[v] > siz[son[now]] ) son[now] = v; } return ; } inline void dfs2( int now, int topf ){ top[now] = topf; if( !son[now] ) return ; dfs2( son[now], topf ); for( rint i = head[now]; i; i = a[i].nxt ){ int v = a[i].to; if( v == fa[now] || v == son[now] ) continue ; dfs2( v, v ); } return ; } inline int lca( int x, int y ){ while( top[x] != top[y] ){ if( dep[top[x]] < dep[top[y]] ) swap( x, y ); x = fa[top[x]]; } if( dep[x] > dep[y] ) return y; else return x; } int main( void ){ n = read(); m = read(); s = read(); for( rint i = 1; i < n; i++ ){ int u, v; u = read(); v = read(); addedge( u, v ); addedge( v, u ); } dfs( s, s, 1 ); dfs2( s, s ); for( rint i = 1; i <= m; i++ ){ int u, v; u = read(); v = read(); printf( "%d\n", lca( u, v ) ); } return 0; }