我不想退役,一定要拿省一
奥利给
1. 堆
#include
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
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
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
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
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
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
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
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;
}
9. 缩点
stack< int > stac;
inline void tarjan( int now ){
dfn[now] = low[now] = ++tot;
stac.push( now ); vis[now] = 1;
for( rint i = head[now]; i; i = a[i].nxt ){
int v = a[i].to;
if( !dfn[v] ){
tarjan( v );
low[now] = min( low[now], dfn[now] );
} else if( vis[v] ) low[now] = min( low[now], low[v] );
}
if( dfn[now] == low[now] ){
++colour;
while( 1 ){
int v = stac.top();
belong[v] = colour;
stac.pop();
vis[v] = 0;
if( v == now ) break ;
}
}
}
10. 割点
#include
using namespace std;
#define rint register int
int n, m, cnt, root = 1, ind, tot;
int head[20010], low[20010], dfn[20010], ans[20010];
struct edge{
int nxt, to;
}a[200010];
inline void addedge( int x, int y ){
a[++cnt].nxt = head[x];
a[cnt].to = y;
head[x] = cnt;
}
inline void tarjan( int fa, int x ){
int child = 0;
++ind;
low[x] = dfn[x] = ind;
for( rint i = head[x]; i; i = a[i].nxt ){
int v = a[i].to;
if( !dfn[v] ){
tarjan( fa, v );
low[x] = min( low[x], low[v] );
if( low[v] >= dfn[x] && x != fa ){
ans[x] = 1;
}
if( x == fa ) child++;
}
low[x] = min( dfn[v], low[x] );
}
if( child >= 2 && x == fa ){
ans[x] = 1;
}
return ;
}
int main( void ){
scanf( "%d%d", &n, &m );
for( rint i = 1; i <= m; i++ ){
int x, y;
scanf( "%d%d", &x, &y );
addedge( x, y );
addedge( y, x );
}
for( rint i = 1; i <= n; i++ ){
if( !dfn[i] ) tarjan( i, i );
}
sort( ans + 1, ans + tot + 1 );
for( rint i = 1; i <= n; i++ ){
if( ans[i] ) ++tot;
}
cout << tot << endl;
for( rint i = 1; i <= n; i++ ){
if( ans[i] )
cout << i << ' ';
}
return 0;
}