前言
【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
",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
",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
");
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
",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
");
else printf("Y
");
}
}
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
",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
",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
");
else printf("No
");
}
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
",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 ",LCA(a,b)); } return 0; }