有序:二分
串变长:先定长
二叉树:三种遍历,记录路径,深搜时要善于利用返回值(一般不让另外开数组维护)
栈与队列:根据所求开辅助栈
数组寻找而不消耗额外空间:把值取反,或者加上最大值令超限
(即用1变-1,或26个字母的话我就加26,以此表示已访问,且可以获取到原值)
二进制下从低位起逐个1消去:n&=(n-1)
二进制下获取最低位1的位置:n&(-n)
链表:同步指针保持差不变,快针&慢针可以求差值
数组找出次数有关的数字:阵地攻守
数组找连续区间或找两个值:尺取法(即左右针)
字符串计数/全排:逐位深搜
实在没有头绪,可以考虑位操作
……跟ACM有很大的不同就是,不会让你打表,不会让你开很大的数组……
下面是今天手撕的模板,有些用不着,有备无患吧
还要补充:多线程
//KMP
#include<bits/stdc++.h>
using namespace std;
int slen,tlen,s[103],t[103],nxt[103];
void getnxt(){
int k=-1,j=0;
nxt[0]=-1;
while(j<tlen){
if(k==-1||t[k]==t[j])nxt[k++]=j++;
else k=nxt[k];
}
}
int kmp_match(){
getnxt();
int k=0,j=0;
while(k<tlen&&j<slen){
if(k==-1||t[k]==s[j])k++,j++;
else k=nxt[k];
}
if(k==tlen)return j-tlen;
else return -1;
}
int main(){
int cas;cin>>cas;
while(cas--){
cin>>slen>>tlen;
for(int i=0;i<slen;i++)cin>>s[i];
for(int i=0;i<tlen;i++)cin>>t[i];
int ans=kmp_match();
if(ans==-1)cout<<ans<<endl;
else cout<<ans+1<<endl;
}
return 0;
}
//heap
#include<bits/stdc++.h>
using namespace std;
int n,tre[103];
void shift_down(int pos){
int flag=0,nxt;
while(pos*2<=n&&flag==0){
nxt=pos;
if(tre[pos]>tre[pos*2])
nxt=pos*2;
if(tre[nxt]>tre[nxt+1])
nxt=nxt+1;
if(nxt!=pos){
int tmp=tre[pos];
tre[pos]=tre[nxt];
tre[nxt]=tmp;
pos=nxt;
}
else{
flag=1;
}
}
}
void heap_push(int x){
n++;
tre[n]=x;
int p=n;
while(tre[p/2]>tre[p]){
swap(tre[p/2],tre[p]);
p/=2;
}
}
int heap_pop(){
int tmp=tre[1];
tre[1]=tre[n--];
shift_down(1);
return tmp;
}
int main(){
heap_push(2);heap_push(4);heap_push(3);heap_push(1);heap_push(5);
cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;cout<<heap_pop()<<endl;
return 0;
}
//线段树
#include<bits/stdc++.h>
using namespace std;
int tre[1003*4];
int query(int l,int r,int id,int x,int y){
int ans=0;
if(x<=l&&r<=y){
ans+=tre[id];
return ans;
}
int mid=(l+r)/2;
if(x<=mid)ans+=query(l,mid,id*2,x,y);
if(y>mid)ans+=query(mid+1,r,id*2+1,x,y);
return ans;
}
void update(int l,int r,int id,int x,int y){
if(l>=r){
tre[id]+=y;
return ;
}
int mid=(l+r)/2;
if(mid>=x)update(l,mid,id*2,x,y);
else update(mid+1,r,id*2+1,x,y);
tre[id]=tre[id*2]+tre[id*2+1];
}
int main(){
update(1,10,1,2,2);
update(1,10,1,3,5);
update(1,10,1,6,7);
cout<<query(1,10,1,1,10)<<endl;
cout<<query(1,10,1,2,2)<<endl;
cout<<query(1,10,1,3,6)<<endl;
return 0;
}
//去重
#include<bits/stdc++.h>
using namespace std;
int main(){
int b[10]={1,1,2,2,3,4,5,5,6,7};
int n=unique(b,b+10)-b;
for(int i=0;i<n;i++)
cout<<b[i]<<endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int>a={1,1,2,2,3,3,4,4,5,6,7};
a.erase(unique(a.begin(),a.end()),a.end());
for(vector<int>::iterator ite=a.begin();ite!=a.end();ite++)
cout<<(*ite)<<endl;
return 0;
}
//floyd
#include<bits/stdc++.h>
using namespace std;
int floyd[103][103];
int main(){
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
cin>>floyd[i][j];
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
if(floyd[i][j]>floyd[i][k]+floyd[k][j])
floyd[i][j]=floyd[i][k]+floyd[k][j];
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
cout<<floyd[i][j]<<' ';
cout<<endl;
}
return 0;
}
//dij
#include<bits/stdc++.h>
using namespace std;
struct edge{
int to;
int cost;
};
vector<edge>g[103];
typedef pair<int,int> p;
int d[103];
void addedge(int from,int to,int cost){
g[from].push_back(edge{to,cost});
g[to].push_back(edge{from,cost});
}
void dij(int s){
priority_queue<p,vector<p>,greater<p> >pq;
pq.push(p(0,s));
memset(d,100,sizeof(d));
d[1]=0;
while(!pq.empty()){
p pp=pq.top();pq.pop();
int nowp=pp.second;
if(d[nowp]>pp.first)continue;
for(int i=0;i<g[nowp].size();i++){
int newp=g[nowp][i].to;
int cst=g[nowp][i].cost;
if(d[newp]>d[nowp]+cst){
d[newp]=d[nowp]+cst;
pq.push(p(d[newp],newp));
}
}
}
}
int main(){
addedge(1,2,3);addedge(1,3,5);addedge(1,4,6);
addedge(2,3,1);addedge(2,4,3);addedge(3,4,1);
dij(1);
cout<<d[1]<<' '<<d[2]<<' '<<d[3]<<' '<<d[4]<<endl;
return 0;
}
//pri
#include<bits/stdc++.h>
using namespace std;
struct edge{int to;int cost;};
vector<edge>g[103];
typedef pair<int,int> p;
void addedge(int from,int to,int cost){
g[from].push_back(edge{to,cost});
g[to].push_back(edge{from,cost});
}
int fa[103],ans;
void prim(int s){
priority_queue<p,vector<p>,greater<p> >pq;
pq.push(p(0,s));
while(!pq.empty()){
//cout<<fa[1]<<' '<<fa[2]<<' '<<fa[3]<<' '<<fa[4]<<' '<<ans<<endl;
p pp=pq.top();pq.pop();
int nowp=pp.second;
if(nowp!=s&&fa[nowp]==s)continue;
fa[nowp]=s;
ans+=pp.first;
for(int i=0;i<g[nowp].size();i++){
int newp=g[nowp][i].to;
int cst=g[nowp][i].cost;
if(s==fa[newp])continue;
pq.push(p(cst,newp));
}
}
}
int main(){
addedge(1,2,3);addedge(1,3,5);addedge(1,4,6);
addedge(2,3,1);addedge(2,4,3);addedge(3,4,1);
for(int i=1;i<=4;i++)fa[i]=i;
prim(1);
cout<<ans<<endl;
return 0;
}
//kru
#include<bits/stdc++.h>
using namespace std;
struct edge{int from;int to;int cost;};
vector<edge>g;
int fa[103],ans;
int fid(int x){
if(x==fa[x])return x;
else return fa[x]=fid(fa[x]);
}
bool cmp(edge a,edge b){
if(a.cost<b.cost)return true;
else return false;
}
void kru(){
sort(g.begin(),g.end(),cmp);
for(int i=0;i<g.size();i++){
int x=fid(g[i].from);
int y=fid(g[i].to);
if(x==y)continue;
ans+=g[i].cost;
fa[x]=y;
}
}
int main(){
g.push_back(edge{1,2,3});g.push_back(edge{1,3,5});g.push_back(edge{1,4,6});
g.push_back(edge{2,3,1});g.push_back(edge{2,4,3});g.push_back(edge{3,4,10});
for(int i=1;i<=4;i++)fa[i]=i;
kru();
cout<<ans<<endl;
return 0;
}
//全排
#include<bits/stdc++.h>
using namespace std;
int sum=0;
bool check(char s[],int l,int r){
for(int i=l;i<r;i++){
if(s[i]==s[r])return false;
}
return true;
}
void perm(char s[],int l,int r){
if(l==r){
cout<<s<<endl;
sum++;
}
else{
for(int i=l;i<=r;i++){
if(check(s,l,i)){
swap(s[l],s[i]);
perm(s,l+1,r);
swap(s[l],s[i]);
}
}
}
}
int main(){
char s[103];
cin>>s;
int len=strlen(s);
perm(s,0,len-1);
cout<<sum<<endl;
return 0;
}
//三分
#include<bits/stdc++.h>
using namespace std;
double f(double x){
return x*x+9*x+10;
}
int main(){
double l=-10000,r=10000;
while(r-l>1e-3){
double x=l+(r-l)/3;
double y=l+(r-l)/3*2;
if(f(x)>f(y))l=x;
else r=y;
}
cout<<l<<' '<<f(l)<<endl;
return 0;
}
//二分
#include<bits/stdc++.h>
using namespace std;
double f(double x){
return x*3;
}
int main(){
double l=-987,r=345;
while(r-l>1e-3){
double mid=(l+r)/2;
if(f(mid)>0)r=mid;
else l=mid;
}
cout<<l<<' '<<f(l)<<endl;
return 0;
}
//筛素数
#include <bits/stdc++.h>
using namespace std;
int vis[10000],pri[10000];
int main(){
int d=sqrt(10000.0);
for(int i=3;i<d;i+=2)
if(!vis[i])
for(int j=i*3;j<d;j+=2*i)
vis[j]=true;
pri[1]=2;
for(int id=2,i=3;i<d;i+=2)
if(!vis[i])pri[id++]=i;
int n;cin>>n;
cout<<pri[n]<<endl;
return 0;
}
//快速幂
#include <bits/stdc++.h>
using namespace std;
int ksm(int x,int y){
int ans=1;
while(y>0){
if(y&1)ans*=x;
y>>=1;
x*=x;
}
return ans;
}
int main(){
int x,y;cin>>x>>y;
cout<<ksm(x,y)<<endl;
return 0;
}
//矩阵快速幂
#include<bits/stdc++.h>
using namespace std;
struct mat{int m[103][103];}unit;
int n,p;
mat operator*(mat a,mat b){
mat ans;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int x=0;
for(int k=0;k<n;k++){
x+=a.m[i][k]*b.m[k][j];
}
ans.m[i][j]=x;
}
}
return ans;
}
mat pos_mat(mat a,int p){
mat ans=unit;
while(p){
if(p&1)ans=ans*a;
a=a*a;
p>>=1;
}
return ans;
}
int main(){
for(int i=0;i<100;i++)unit.m[i][i]=1;
cin>>n>>p;
mat a;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>a.m[i][j];
a=pos_mat(a,p);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
cout<<a.m[i][j]<<' ';
cout<<endl;
}
return 0;
}
//merge_sort
#include <bits/stdc++.h>
using namespace std;
void merge_sort(int a[],int l,int r){
if(l>=r)return ;
int mid=(l+r)/2;
merge_sort(a,l,mid);
merge_sort(a,mid+1,r);
int tmp[10],k=l,i=l,j=mid+1;
while(i<=mid&&j<=r){
if(a[i]<a[j])tmp[k++]=a[i++];
else tmp[k++]=a[j++];
}
while(i<=mid)tmp[k++]=a[i++];
while(j<=r)tmp[k++]=a[j++];
for(int i=l;i<=r;i++)a[i]=tmp[i];
}
int main(){
int a[10]={9,8,7,6,5,4,3,2,1,0};
merge_sort(a,0,9);
for(int i=0;i<10;i++)
cout<<a[i]<<' ';
return 0;
}
//字典树
#include<bits/stdc++.h>
using namespace std;
struct node{
int cnt;
struct node* nxt[26];
node(){
cnt=0;
for(int i=0;i<26;i++)
nxt[i]=NULL;
}
};
node* root;
char str[103][30];
void maketrie(char *s){
node* p=root;
node* tmp=NULL;
for(int i=0;i<strlen(s);i++){
if(p->nxt[s[i]-'a']==NULL){
tmp=new node;
p->nxt[s[i]-'a']=tmp;
}
p=p->nxt[s[i]-'a'];
p->cnt++;
}
}
void search(char *s){
node *p=root;
for(int i=0;i<strlen(s);i++){
p=p->nxt[s[i]-'a'];
cout<<s[i];
if(p->cnt==1)break;
}
}
int main(){
root=new node;
int n;cin>>n;
for(int i=0;i<n;i++){
cin>>str[i];
maketrie(str[i]);
}
for(int i=0;i<n;i++){
cout<<str[i]<<' ';
search(str[i]);
cout<<endl;
}
return 0;
}
/*
input:
12
carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate
output:
carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona
*/