前言
【2017-11-10】
哇!突然发现搜索‘模板’能搜到一坨。。。开始了默默刷模板的漫长之路。。。就让我最后在挣扎一下下吧!!!
【2017-11-18】
考完试了,忽然就发现,原来,不会的东西现学不可能会使用上的。。除了我瞎写的dijkstra,没用上这些模板,noip甚至连暴力都没写好。心态爆炸。
嗯,还是在AFO后好好学文化课吧!
板砸们
1. P1177 【模板】快速排序
好吧,不可相信这也是个模板。。
虽然说的那么。。那什么。。可是,真的不想自己弄唉(STL大法好)
代码酱=u=
①sort大法好!
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int n; long long a[100010]; int main() { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%lld",&a[i]); sort(a,a+n); for(int i=0; i<n; i++) printf("%lld ",a[i]); return 0; }
②真板子
——快速排序
#include <iostream> #include <cstdio> #include <algorithm> #define mid ((l+r)>>1) #define LL long long using namespace std; int n; LL a[100010]; void Mysort(int l,int r) { int i=l,j=r,m=a[mid]; while(i<=j) { while(a[i]<m) i++; while(a[j]>m) j--; if(i<=j) { LL tmp=a[i]; a[i]=a[j],a[j]=tmp; i++,j--; } } if(l<j) Mysort(l,j); if(i<r) Mysort(i,r); } int main() { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%lld",&a[i]); Mysort(0,n-1); for(int i=0; i<n; i++) printf("%lld ",a[i]); return 0; }
——归并排序
#include <iostream> #include <cstdio> #define LL long long using namespace std; const int M = 100010; int n; LL a[M],b[M]; void gsort(int l,int r) { if(l==r) return; int mid=l+r>>1; gsort(l,mid),gsort(mid+1,r); int i=l,j=mid+1,k=l; while(i<=mid && j<=r) { if(a[i]<=a[j]) b[k++]=a[i++]; else b[k++]=a[j++]; } while(i<=mid) b[k++]=a[i++]; while(j<=r) b[k++]=a[j++]; for(int q=l; q<=r; q++) a[q]=b[q]; } int main() { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%lld",&a[i]); gsort(1,n); for(int i=1; i<=n; i++) printf("%lld ",a[i]); return 0; }
2. P1439 【模板】最长公共子序列
我以前原来没做过qaq,这样的板子题。。意会了好久233
思路
我们可以以第一个串为标准,用第二个串来匹配第一个串,看能匹配多少。
所以,其实第一个串的每个数字其实影响不大,只有知道它对应了第二串的哪个数字就行,然后最后只要求一下上升序列就好辣~
代码酱qaq
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int M = 100010; int n,len; int a[M],b[M],belong[M]; int main() { scanf("%d",&n); //离散化一下 for(int i=1,x; i<=n; i++) { scanf("%d",&x); belong[x]=i; } for(int i=1,x; i<=n; i++) { scanf("%d",&x); a[i]=belong[x]; } for(int i=1; i<=n; i++) { //find上升序列 if(a[i]>b[len]) { b[++len]=a[i]; continue; } int k=lower_bound(b+1,b+1+len,a[i])-b; b[k]=a[i]; } printf("%d\n",len); return 0; }
3. P3390 【模板】矩阵快速幂
今天刚学会qaq,考前的学新东西之一233
具体的嘛~我表示,只会背过+推矩阵
代码酱(*/ω\*)
#include <iostream> #include <cstdio> typedef long long LL; using namespace std; inline LL readl() { LL x=0,f=1; char c=getchar(); while(c<'0' || c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0' && c<='9') x=x*10+c-'0',c=getchar(); return x*f; } const int Mod = 1000000007; LL n,m,i,j,k; struct A { LL a[105][105]; inline A operator * (const A &b) const { A ret; for(LL i=1; i<=n; i++) for(LL j=1; j<=n; j++) { ret.a[i][j]=0; for(LL k=1; k<=n; k++) ret.a[i][j]+=a[i][k]*b.a[k][j], ret.a[i][j]%=Mod; } return ret; } }q; A ksm(A a,LL x) { A ret,k; ret=a,k=a; x--; for(; x; x>>=1,k=k*k) if(x&1) ret=ret*k; return ret; } int main() { n=readl();m=readl(); for(i=1; i<=n; i++) for(j=1; j<=n; j++) q.a[i][j]=readl(); q=ksm(q,m); for(i=1; i<=n; i++) { for(j=1; j<n; j++) printf("%d ",q.a[i][j]); printf("%d\n",q.a[i][n]); } return 0; }
4. P1939 【模板】矩阵加速(数列)
思路
先看这个特征方程F[i] = F[i - 1] + F[i - 3],那么就有一个矩阵如下
我们的目标矩阵就是
那么,针对这个矩阵我们如何转置呢?
先看目标矩阵第一个:F[i]
F[i] = F[i - 1] + F[i - 3]
那么,由矩阵乘法,转置矩阵第一行,似乎就定了:1 0 1
同样的,二三行就是1 0 0 和 0 1 0
整个矩阵如下:
至于转置矩阵和初始矩阵的用法?
矩阵快速幂什么各种杂七杂八的
代码酱_(:з」∠)_
#include <iostream> #include <cstdio> #define LL long long using namespace std; inline LL read() { LL x=0,f=1; char c=getchar(); while(c<'0' || c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0' && c<='9') x=x*10+c-48,c=getchar(); return x*f; } const int Mod = 1000000007; LL T,n; struct Q { LL a[5][5]; Q operator * (const Q &b) const { Q ret; for(int i=1; i<=3; i++) for(int j=1; j<=3; j++) { ret.a[i][j]=0; for(int k=1; k<=3; k++) ret.a[i][j]+=a[i][k]*b.a[k][j]; ret.a[i][j]%=Mod; } return ret; } }A,B; inline Q ksm(Q A,LL x) { Q ret=A,k=A; x--; for(; x; x>>=1,k=k*k) if(x&1) ret=ret*k; return ret; } int main() { T=read(); while(T--) { n=read(); if(n<=3) { printf("1\n"); continue; } else { A.a[1][1]=A.a[1][3]=A.a[2][1]=A.a[3][2]=1; A.a[1][2]=A.a[2][2]=A.a[2][3]=A.a[3][1]=A.a[3][3]=0; B.a[1][1]=B.a[1][2]=B.a[1][3]=1; Q P=ksm(A,n); printf("%lld\n",P.a[1][3]); } } return 0; }
5. P3367 【模板】并查集
呼~今天刚整理了这个qaq,还好还有印象。。。
代码酱(≧▽≦)/
#include <iostream> #include <cstdio> using namespace std; const int N = 10010; int n,m; int dad[N]; inline int getdad(int x) { return x == dad[x] ? x : dad[x]=getdad(dad[x]); } inline void Union(int u,int v) { int f1=getdad(u),f2=getdad(v); if(f1!=f2) dad[f1]=f2; } int main() { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) dad[i]=i; for(int i=1,x,u,v; i<=m; i++) { scanf("%d%d%d",&x,&u,&v); if(x==1) { Union(u,v); } else { int f1=getdad(u),f2=getdad(v); if(f1!=f2) printf("N\n"); else printf("Y\n"); } } return 0; }
6. P3372 【模板】线段树 1
坑点
第一次交上竟然WA了qaq,我我我我原来是更新区间的时候忘记乘以长度了qaq,再犯蠢就打我自己qaq
代码酱(╥╯^╰╥)
#include <iostream> #include <cstdio> #define mid ((l+r)>>1) #define lson rt<<1 #define rson rt<<1|1 #define LL long long using namespace std; const int M = 100001; int n,m,a,b,x,s[M]; LL ans; struct Tree { LL l,r,w,f; } t[M<<2]; inline void update(int rt) { int l=t[rt].l,r=t[rt].r; t[rt].w=t[lson].w+t[rson].w; } inline void build(int rt,int l,int r) { t[rt].l=l,t[rt].r=r,t[rt].f=0; if(l==r) { t[rt].w=s[l]; return ; } build(lson,l,mid); build(rson,mid+1,r); update(rt); } inline void down(int rt) { int l=t[rt].l,r=t[rt].r; t[lson].f+=t[rt].f; t[rson].f+=t[rt].f; t[lson].w+=t[rt].f*(t[lson].r-t[lson].l+1); t[rson].w+=t[rt].f*(t[rson].r-t[rson].l+1); t[rt].f=0; } inline void addq(int rt) { int l=t[rt].l,r=t[rt].r; if(a<=l && r<=b) { t[rt].f+=x; t[rt].w+=(t[rt].r-t[rt].l+1)*x; return ; } if(t[rt].f) down(rt); if(a<=mid) addq(lson); if(b>mid) addq(rson); update(rt); } inline void asksum(int rt) { int l=t[rt].l,r=t[rt].r; if(a<=l && r<=b) { ans+=t[rt].w; return ; } if(t[rt].f) down(rt); if(a<=mid) asksum(lson); if(b>mid) asksum(rson); } int main() { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) scanf("%lld",&s[i]); build(1,1,n); for(int i=1,q; i<=m; i++) { scanf("%d",&q); if(q==1) { scanf("%d%d%d",&a,&b,&x); addq(1); } else { scanf("%d%d",&a,&b); asksum(1); printf("%lld\n",ans); ans=0; } } return 0; }
7. P3366 【模板】最小生成树
坑点 n,m顺序。。。
代码酱(・∀・)
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N = 5050; const int M = 200020; int n,m,ans; int dad[N]; struct A { int u,v,w; bool operator < (const A &qwq) const { return w < qwq.w; } }e[M]; int getdad(int x) { return x == dad[x] ? x : dad[x]=getdad(dad[x]); } int main() { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) dad[i]=i; for(int i=1; i<=m; i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); sort(e+1,e+m+1); //m!!! for(int i=1; i<=m; i++) { int f1=getdad(e[i].u), f2=getdad(e[i].v); if(f1!=f2) { dad[f1]=f2; ans+=e[i].w; } } int tmp=getdad(1); for(int i=1; i<=n; i++) if(getdad(i)!=tmp) { printf("orz"); return 0; } printf("%d",ans); return 0; }
8. P3375 【模板】KMP字符串匹配
麻吉一A开熏qaq
代码酱(:3_ヽ)_
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int M = 1000010; char s[M],p[M]; int lens,lenp; int nxt[M]; void getnxt() { nxt[0]=-1,nxt[1]=0; int k=0,j=1; while(j<lenp) { if(k==-1 || p[k]==p[j]) { k++,j++; nxt[j]=k; } else k=nxt[k]; } } void KMP() { int i=0,j=0; while(i<lens) { if(s[i]==p[j]) i++,j++; else if(j>=0) j=nxt[j]; else i++,j=0; if(j==lenp) { int ans=i-j+1; printf("%d\n",ans); } } } int main() { cin>>s;lens=strlen(s); cin>>p;lenp=strlen(p); getnxt(); KMP(); for(int i=1; i<=lenp; i++) printf("%d ",nxt[i]); return 0; }
9. P3371 【模板】单源最短路径
新学到dijkstra!!!防止spfa被卡。。。
dijkstra大法好!priority_queue大法好!
代码酱。◕ᴗ◕。
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; const int INF = 2147483647; const int N = 10010; const int M = 500050; struct rp { int next,to,w; } e[M]; int top,head[N]; void add(int u,int v,int w) { top++; e[top].to=v; e[top].w=w; e[top].next=head[u]; head[u]=top; } int n,m,s; int dis[N],vis[N]; struct node { int x,dis; bool operator < (node a) const { return dis > a.dis; } }; void spfa(int x) { memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[x]=0;vis[x]=1; queue<int>que; que.push(x); int u,v; while(!que.empty()) { u=que.front();que.pop(); for(int i=head[u]; i; i=e[i].next) { v=e[i].to; if(dis[v]>dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; if(!vis[v]) { vis[v]=1; que.push(v); } } } vis[u]=0; } } void dijkstra(int x) { priority_queue<node>q; memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[x]=0; q.push((node){x,0}); while(!q.empty()) { node u=q.top();q.pop(); if(vis[u.x]) continue; vis[u.x]=1; for(int i=head[u.x]; i; i=e[i].next) { int v=e[i].to; if(dis[v]>dis[u.x]+e[i].w) { dis[v]=dis[u.x]+e[i].w; q.push((node){v,dis[v]}); } } } } int main() { scanf("%d%d%d",&n,&m,&s); for(int i=1,u,v,w; i<=m; i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); } // spfa(s); dijkstra(s); for(int i=1; i<=n; i++) if(dis[i]==0x3f3f3f3f) printf("%d ",INF); else printf("%d ",dis[i]); return 0; }
10.P3383 【模板】线性筛素数
表示第一次交RE。。。找了一下原来是筛素数的时候i*prime[j]写成了j*prime[j]。。。蠢死了
代码酱(;д;)
#include <iostream> #include <cstdio> using namespace std; const int N = 10000010; int n,m,cnt; int prime[N>>1],vis[N]; void getprime() { vis[0]=vis[1]=1; for(int i=2; i<=n; i++) { if(!vis[i]) prime[++cnt]=i; for(int j=1; j<=cnt && i*prime[j]<=n; j++) { //就这里qaq vis[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int main() { scanf("%d%d",&n,&m); getprime(); for(int i=1,x; i<=m; i++) { scanf("%d",&x); if(!vis[x]) printf("Yes\n"); else printf("No\n"); } return 0; }
11.P3378 【模板】堆
嗦一下:STL大法好!!!
代码酱(❁´ω`❁)
#include <iostream> #include <cstdio> #include <queue> //使用堆(优先队列)的头文件 using namespace std; int n; priority_queue<int,vector<int>,greater<int> >q; //小根堆... //大根堆长这样->priority_queue<int>que; int main() { scanf("%d",&n); for(int i=1,p,x; i<=n; i++) { scanf("%d",&p); if(p==1) { scanf("%d",&x); q.push(x); } else if(p==2) printf("%d\n",q.top()); else q.pop(); } return 0; }
12.P3370 【模板】字符串哈希
哇!刚在网上找到一个写的炒鸡漂漂滴模板,赶紧敲了一下!!!超满意!!!
代码酱(๑¯∀¯๑)
①刚学的!(作死)
#include <iostream> #include <cstdio> #include <string> using namespace std; const int size = 15000; int n,cnt=0; string tmp,hash[size]; int calc(string& x) { int ret=0; for(int i=0; i<x.length(); i++) ret=(ret*256+x[i]+128)%size; return ret; } bool search(string& x,int& pos) { pos=calc(x); while(hash[pos]!="" && hash[pos]!=x) pos=(pos+1)%size; if(hash[pos]==x) return true; else return false; } int Insert(string& x) { int pos; if(search(x,pos)) return 0; else { hash[pos]=x; return 1; } } int main() { cin>>n; for(int i=0; i<n; i++) { cin>>tmp; cnt+=Insert(tmp); } cout<<cnt<<endl; return 0; }
②以前的巨丑代码
#include <iostream> #include <cstdio> #include <set> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ull; typedef long long LL; set<ull>ssr; const int N = 2333; const int D = 131; const ull Mod = 1e9+7; LL n,len; string s; ull f[N],g[N]; void pre(int m) { memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); f[0]=s[0]; for(int i=1; i<=m; i++) f[i]=(1LL*f[i-1]*D+s[i-1])%Mod; g[0]=1; for(int i=1; i<=m; i++) g[i]=1LL*g[i-1]*D%Mod; } int Hash(int l,int r) { ull a=f[r]; ull b=1LL*f[l-1]*g[r-l+1]%Mod; return (a-b+Mod)%Mod; } int main() { cin>>n; while(n--) { cin>>s; len=s.length(); pre(len); ull q=Hash(1,len); ssr.insert(q); } cout<<ssr.size(); return 0; }
13.P3379 【模板】最近公共祖先(LCA)
代码酱o( =•ω•= )m
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const int M = 500050; int n,m,s,p,num; int dep[M],jumps[M][21]; int top,head[M]; bool vis[M]; struct A { int next,to; } e[M<<1]; void add(int u,int v) { top++; e[top].to=v; e[top].next=head[u]; head[u]=top; } void Dfs(int u) { for(int i=head[u],v; i; i=e[i].next) { v=e[i].to; if(dep[v]==0) { dep[v]=dep[u]+1; jumps[v][0]=u; Dfs(v); } } } void getstep() { for(int i=1; i<=20; i++) for(int j=1; j<=n; j++) jumps[j][i]=jumps[jumps[j][i-1]][i-1]; } int LCA(int a,int b) { if(dep[a]<dep[b]) swap(a,b); for(int i=20; i>=0; i--) if(dep[jumps[a][i]]>=dep[b]) a=jumps[a][i]; if(a==b) return b; for(int i=20; i>=0; i--) if(jumps[a][i]!=jumps[b][i]) a=jumps[a][i],b=jumps[b][i]; return jumps[a][0]; } int main() { scanf("%d%d%d",&n,&m,&s); for(int i=1,u,v; i<n; i++) { scanf("%d%d",&u,&v); add(u,v),add(v,u); } dep[s]=1; Dfs(s); getstep(); int a,b; while(m--) { scanf("%d%d",&a,&b); printf("%d\n",LCA(a,b)); } return 0; }
表情包们
o( =•ω•= )m
٩(๑`^´๑)۶
(:3▓▒
ヾ(o◕∀◕)ノヾ
= ̄ω ̄=
n(*≧▽≦*)n
(๑´ㅂ`๑)ε
≡٩(๑>₃<)۶
*✧⁺˚⁺ପ(๑・ω・)੭ु⁾⁾
*:ஐ٩(๑´ᵕ`)۶ஐ:*
(っ•̀ω•́)っ✎⁾⁾
٩꒰▽ ꒱۶⁼³₌₃
…φ(๑˃∀˂๑)♪
(๑╹ヮ╹๑)ノ
ヾヾ( ˘ ³˘人)ヾ
٩(๑❛ᴗ❛๑)۶
ヾ(❀●◡●)ノ
( ー̀ωー́ )⊃⌒
φ(>ω<*)
(。・ω・。)
(*・ω-q)
(〃´-ω・)
(>ω・* )ノ
( • ̀ω•́ )✧
ヾ(=・ω・=)o
(=´ω`=)
d(´ω`*)
( ・´ω`・ )
(๑>ڡ<)☆
ヾ(◍°∇°◍)ノ゙
ヾ(๑╹◡╹)ノ"
⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄
(..›ᴗ‹..)
(づ◡ど)
(ฅ'ω'ฅ)♪
(ミ´ω`ミ)
ฅ(*`ω´*)ฅ