[洛谷模板大赛]题解 模板整理QAQ
来源:互联网 发布:java 代码整洁之道 编辑:程序博客网 时间:2024/05/17 07:08
题目地址:NOIP RP++
题目描述不用说,都是交模板就能AC的,昨晚就A了4个题因为时间不太够了……
最近也想整理模板,看到这么个模板大赛自然是把持不住辣~
除了T2平衡树不会做之外其他的都可以,T5好像是递归版Spfa,现学了一下,其实思想都一样,不用学,其他的没什么了,看模板~
T1:线段树:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>#define lson p<<1#define rson p<<1|1using namespace std;typedef long long LL;const int SIZE = 500010;struct Tree{ int l,r; LL sum,add;}tree[SIZE<<2];void build(int p,int l,int r){ tree[p].l = l,tree[p].r = r; if(l == r) return ; int mid = (l + r) >> 1; build(lson,l,mid); build(rson,mid+1,r);}inline void RD(int &x){ x = 0; char c; c = getchar(); bool flag = 0; if(c == '-') flag = 1; while(c < '0' || c > '9') { if(c == '-') flag = 1; c = getchar(); } while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0',c = getchar(); if(flag) x = -x;}void spread(int p){ if(tree[p].add) { tree[lson].sum += (LL)(tree[lson].r - tree[lson].l + 1) * tree[p].add; tree[rson].sum += (LL)(tree[rson].r - tree[rson].l + 1) * tree[p].add; tree[lson].add += tree[p].add; tree[rson].add += tree[p].add; tree[p].add = 0; }}void change(int p,int l,int r,int x){ if(l <= tree[p].l && tree[p].r <= r) { tree[p].sum += (LL)x * (tree[p].r - tree[p].l + 1); tree[p].add += (LL)x; return ; } spread(p); int mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid) change(lson,l,r,x); if(mid < r) change(rson,l,r,x); tree[p].sum = tree[lson].sum + tree[rson].sum;}LL ask(int p,int l,int r){ if(l <= tree[p].l && tree[p].r <= r) return tree[p].sum; spread(p); LL ans = 0; int mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid) ans += ask(lson,l,r); if(mid < r) ans += ask(rson,l,r); return ans;}int n,m,q,l,r;int x;int main(){ RD(n); RD(m); build(1,1,n); while(m--) { RD(q); if(q == 2) { RD(l); RD(r); RD(x); change(1,l,r,x); } if(q == 1) { RD(l); RD(r); printf("%lld\n",ask(1,l,r)); } } return 0;}
T2:平衡树(听说线段树能做我也没仔细看……)
T3:堆
需要注意一下,把删除操作替换掉,就是每次要删除时直接标记那个数,等到查询那个数的时候再删除那个数,这样正确性仍然是能保证的~
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<map>using namespace std;typedef long long LL;map <int,bool> vis;inline void RD(int &x){ x = 0; char c; c = getchar(); bool flag = 0; if(c == '-') flag = 1; while(c < '0' || c > '9') { if(c == '-') flag = 1; c = getchar(); } while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0',c = getchar(); if(flag) x = -x;}priority_queue <int> q;int n,a;int main(){ RD(n); while(n--) { RD(a); if(a > 0) q.push(a); else if(a == 0) { while(vis[q.top()]) q.pop(); printf("%d\n",q.top()); } else if(a < 0) vis[-a] = 1; } return 0;}
T4:二分图的最大匹配
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>using namespace std;typedef long long LL;const int SIZE = 500010;struct Edge{int to;}edges[SIZE];int head[SIZE],next[SIZE],tot;void build(int f,int t){ edges[++tot].to = t; next[tot] = head[f]; head[f] = tot;}inline void RD(int &x){ x = 0; char c; c = getchar(); bool flag = 0; if(c == '-') flag = 1; while(c < '0' || c > '9') {if(c == '-') {flag = 1;} c = getchar();} while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0',c = getchar();}bool vis[SIZE];int connect[SIZE << 1];bool dfs(int u){ for(int i = head[u];i;i = next[i]) { int v = edges[i].to; if(!vis[v]) { vis[v] = 1; if(!connect[v] || dfs(connect[v])) { connect[v] = u; return true; } } } return false;}int n,m,k,a,b;int main(){ RD(n),RD(m),RD(k); int mx = max(n,m); while(k --) { RD(a),RD(b); build(a,b+mx); } int cnt = 0; for(int i = 1;i <= n;i ++) { memset(vis,0,sizeof(vis)); if(dfs(i)) cnt ++; } printf("%d\n",cnt); return 0;}
T5:最短路
注意开long long ,以及把变量开在外面这个细节~
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<cmath>using namespace std;typedef long long LL;const int SIZE = 200010;const LL INF = 2147483647233LL;struct Edge{int to;LL dist;}edges[SIZE];int head[SIZE],next[SIZE],tot;void build(int f,int t,LL d){ edges[++tot].to = t; edges[tot].dist = d; next[tot] = head[f]; head[f] = tot;}deque <int> q;LL dist[SIZE];bool vis[SIZE];int n,m,s,t;void spfa(){ for(int i = 1;i <= n;i ++) dist[i] = INF; q.push_back(s); vis[s] = 1; dist[s] = 0; while(!q.empty()) { int f = q.front(); q.pop_front(); vis[f] = 0; for(int i = head[f];i;i = next[i]) { int v = edges[i].to; if(dist[v] > dist[f] + edges[i].dist) { dist[v] = dist[f] + edges[i].dist; if(!vis[v]) { vis[v] = 1; if(!q.empty() && dist[v] < dist[q.front()]) q.push_front(v); else q.push_back(v); } } } }}int a,b;LL c;int main(){ scanf("%d%d",&n,&m); for(int i = 1;i <= m;i ++) { scanf("%d %d %lld",&a,&b,&c);// cout<<a<<" "<<b<<" "<<c<<endl; build(a,b,c); } s = 1,t = n; spfa(); if(dist[t] == INF) puts("-1"); else printf("%lld\n",dist[t]); return 0;}
T6:dfs版的spfa判断负环
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<cmath>using namespace std;typedef long long LL;typedef double DB;const int SIZE = 500010;struct Edge{int to,dist;}edges[SIZE];int head[SIZE],next[SIZE],tot;void build(int f,int t,int d){ edges[++tot].to = t; edges[tot].dist = d; next[tot] = head[f]; head[f] = tot;}int n,m,a,b,c;bool vis[SIZE];int dist[SIZE];bool flag = 0;void spfa(int u){ if(flag) return ; for(int i = head[u];i;i = next[i]) { int v = edges[i].to; if(dist[v] > dist[u] + edges[i].dist) { if(vis[v]) flag = 1; dist[v] = dist[u] + edges[i].dist; if(!vis[v]) { vis[v] = 1; spfa(v); vis[v] = 0; } } }}int main(){ int t; scanf("%d",&t); while(t--) { tot = 0; memset(head,0,sizeof(head)); memset(edges,0,sizeof(edges)); memset(next,0,sizeof(next)); scanf("%d%d",&n,&m); for(int i = 1;i <= m;i ++) { scanf("%d%d%d",&a,&b,&c); build(a,b,c); if(c >= 0) build(b,a,c); } flag = 0; memset(dist,64,sizeof(dist)); for(int i = 1;i <= n;i ++) { if(!vis[i]) { spfa(i); if(flag) {puts("YE5");break;} } } if(!flag) puts("N0"); } return 0;}
T7:tarjian求割点
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<cmath>using namespace std;typedef long long LL;typedef double DB;const int SIZE = 200010;int n,m;struct Edge{int to;}edges[SIZE];int head[SIZE],next[SIZE],tot;void build(int f,int t){ edges[++tot].to = t; next[tot] = head[f]; head[f] = tot;}int dfs_clock,low[SIZE],pre[SIZE];bool iscut[SIZE];bool dfs(int u,int fa){ low[u] = pre[u] = ++dfs_clock; int child = 0; for(int i = head[u];i;i = next[i]) { int v = edges[i].to; if(v == fa) continue; if(!pre[v]) { child ++; dfs(v,u); low[u] = min(low[u],low[v]); if(pre[u] <= low[v]) iscut[u] = true; } else if(pre[v] < pre[u]) { low[u] = min(low[u],pre[v]); } } if(child <= 1 && fa < 0) iscut[u] = false;}int a,b;int main(){ scanf("%d%d",&n,&m); for(int i = 1;i <= m;i ++) { scanf("%d%d",&a,&b); build(a,b); build(b,a); } for(int i = 1;i <= n;i ++) if(!pre[i]) dfs(i,-1); int cnt = 0; for(int i = 1;i <= n;i ++) if(iscut[i]) cnt ++; printf("%d\n",cnt); return 0;}
0 0
- [洛谷模板大赛]题解 模板整理QAQ
- 模板整理---大数模板
- 模板整理
- [无聊]CSDN题解模板
- 最小费用最大流<模板大法好QAQ>
- 六一儿童节题解QAQ
- 【整理】Eclipse注释模板
- 排序模板(整理)
- 网站模板整理
- Templat 模板(整理)
- ECshop模板机制整理
- NOIP 考前模板整理
- 图论模板整理
- 模板整理之KMP
- ACM模板整理
- 【整理】Eclipse注释模板
- 背包整理模板
- 高斯消元模板整理
- Maven项目构建
- JVM/JRE/JDK关系图
- 建立连接的过程
- 删除WKWebView的缓存
- Android--数据库升级,插入新字段
- [洛谷模板大赛]题解 模板整理QAQ
- 子网划分
- Oracle中PCTFREE, PCTUSED, INITRANS, MAXTRANX参数
- Ubuntu下安装Code::Blocks开发环境
- git 备忘与总结
- easyUI,tree,获取一级子节点
- ACboy needs your help again!
- 算法(选择排序的算法)
- 多台tomcat服务的session共享 memcached与redis