十模板HJR
Hjr1141451931 · · 个人记录
赛前必备模板
一.线段树
struct ST{
ll A[MAXN];
struct node{
int l,r;
ll val,lazy;
}tree[MAXN*4];
void build(int u,int l,int r){
tree[u].l=l,tree[u].r=r,tree[u].lazy=0;
if(l==r){tree[u].val=A[l];return;}
int mid=(l+r)/2;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
tree[u].val=tree[u*2].val+tree[u*2+1].val;
return;
}
void Spread(int u){
if(tree[u].lazy){
tree[u*2].val+=tree[u].lazy*(tree[u*2].r-tree[u*2].l+1);
tree[u*2+1].val+=tree[u].lazy*(tree[u*2+1].r-tree[u*2+1].l+1);
tree[u*2].lazy+=tree[u].lazy;
tree[u*2+1].lazy+=tree[u].lazy;
tree[u].lazy=0;
}
}
ll Ask(int u,int l,int r){
int pl=tree[u].l,pr=tree[u].r;
ll val=tree[u].val;
if(l<=pl&&r>=pr) return val;
int mid=(pl+pr)/2;ll ans=0;
Spread(u);
if(l<=mid) ans+=Ask(u*2,l,r);
if(r>=mid+1) ans+=Ask(u*2+1,l,r);
return ans;
}
void Add(int u,int l,int r,ll add){
int pl=tree[u].l,pr=tree[u].r;
if(l<=pl&&r>=pr){tree[u].val+=add*(pr-pl+1);tree[u].lazy+=add;return;}
int mid=(pl+pr)/2;
Spread(u);
if(l<=mid) Add(u*2,l,r,add);
if(r>=mid+1) Add(u*2+1,l,r,add);
tree[u].val=tree[u*2].val+tree[u*2+1].val;
}
}T;
二.树链剖分
#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
template<typename T> inline void read(T &x){
x=0;T w=1,ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
x=x*w;
}
const int MAXN=200005;
int P,top[MAXN],adr[MAXN],tot;
struct node{
int Hc,f,siz,dep,val;
}t[MAXN];
int root;
int n,m;
int head[MAXN],cnt;
struct edge{
int to,nxt;
}e[MAXN];
void add(int u,int v){
cnt++;
e[cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;
}
struct ST{
ll A[MAXN];
struct node{
int l,r;
ll val,lazy;
}tree[MAXN*4];
void build(int u,int l,int r){
tree[u].l=l,tree[u].r=r,tree[u].lazy=0;
if(l==r){tree[u].val=A[l];return;}
int mid=(l+r)/2;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
tree[u].val=tree[u*2].val+tree[u*2+1].val;
return;
}
void Spread(int u){
if(tree[u].lazy){
tree[u*2].val+=tree[u].lazy*(tree[u*2].r-tree[u*2].l+1);
tree[u*2+1].val+=tree[u].lazy*(tree[u*2+1].r-tree[u*2+1].l+1);
tree[u*2].lazy+=tree[u].lazy;
tree[u*2+1].lazy+=tree[u].lazy;
tree[u].lazy=0;
}
}
ll Ask(int u,int l,int r){
int pl=tree[u].l,pr=tree[u].r;
ll val=tree[u].val;
if(l<=pl&&r>=pr) return val;
int mid=(pl+pr)/2;ll ans=0;
Spread(u);
if(l<=mid) ans+=Ask(u*2,l,r);
if(r>=mid+1) ans+=Ask(u*2+1,l,r);
return ans;
}
void Add(int u,int l,int r,ll add){
int pl=tree[u].l,pr=tree[u].r;
if(l<=pl&&r>=pr){tree[u].val+=add*(pr-pl+1);tree[u].lazy+=add;return;}
int mid=(pl+pr)/2;
Spread(u);
if(l<=mid) Add(u*2,l,r,add);
if(r>=mid+1) Add(u*2+1,l,r,add);
tree[u].val=tree[u*2].val+tree[u*2+1].val;
}
}T;
int dfs1(int u){
t[u].siz=1;
int si=0,Hvs=-1;
for(int i=head[u];i;i=e[i].nxt){
if(e[i].to!=t[u].f){
t[e[i].to].f=u,t[e[i].to].dep=t[u].dep+1;
int sic=dfs1(e[i].to);
if(sic>Hvs) Hvs=sic,t[u].Hc=e[i].to;
si+=sic;
}
}
t[u].siz+=si;
return t[u].siz;
}
void dfs2(int u,int tp){
top[u]=tp;
adr[u]=++tot;
T.A[tot]=t[u].val;
if(t[u].Hc!=u&&t[u].Hc) dfs2(t[u].Hc,tp);
for(int i=head[u];i;i=e[i].nxt)
if(e[i].to!=t[u].Hc&&e[i].to!=t[u].f) dfs2(e[i].to,e[i].to);
return;
}
void Radd(int x,int y,int val){
while(top[x]!=top[y]){
if(t[top[x]].dep<t[top[y]].dep) swap(x,y);
T.Add(1,adr[top[x]],adr[x],val);
x=t[top[x]].f;
}
if(t[x].dep>t[y].dep) swap(x,y);
T.Add(1,adr[x],adr[y],val);
}
ll qRange(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(t[top[x]].dep<t[top[y]].dep) swap(x,y);
ans+=T.Ask(1,adr[top[x]],adr[x]);
ans%=P;
x=t[top[x]].f;
}
if(t[x].dep>t[y].dep) swap(x,y);
return (ans+T.Ask(1,adr[x],adr[y]))%P;
}
void adds(int x,int val){
T.Add(1,adr[x],adr[x]+t[x].siz-1,val);
}
ll qs(int x){
return T.Ask(1,adr[x],adr[x]+t[x].siz-1)%P;
}
signed main()
{
cin>>n>>m>>root>>P;
for(int i=1;i<=n;i++) cin>>t[i].val;
for(int i=1;i<=n-1;i++){
int a,b;
read(a),read(b);
add(a,b),add(b,a);
}
t[root].dep=1;
dfs1(root);
dfs2(root,root);
T.build(1,1,n);
for(int i=1;i<=m;i++){
int o,x,y,z;
read(o),read(x);
if(o==1){
read(y),read(z);
Radd(x,y,z);
}
if(o==2){
read(y);
cout<<qRange(x,y)<<endl;
}
if(o==3){
read(y);
adds(x,y);
}
if(o==4) cout<<qs(x)<<endl;
}
return 0;
}
三.最短路
#include<bits/stdc++.h>
using namespace std;
int n,m,st;
bool book[1000005];
struct edge
{
int to,val;
};
struct node
{
int d,upper;
int operator <(const node &b)
const{
return d>b.d;
}
};
vector <edge> s[2000005];
int dis[1000005];
priority_queue<node> q;
void dijkstra()
{
while(!q.empty())
{
while(book[q.top().upper]&&q.top().upper!=st){
if(q.empty())
return;
q.pop();
}
int u=q.top().upper;
book[u]=true;
int v=dis[u];
for(int i=0;i<s[u].size();i++)
{
int t=s[u][i].to;
if(s[u][i].val+v<dis[t]&&!book[t])
dis[t]=s[u][i].val+v;
if(!book[t])
q.push({dis[t],t});
}
q.pop();
}
}
int main()
{
memset(dis,0x3f3f3f3f,sizeof(dis));
cin>>n>>m>>st;
dis[st]=0;
book[st]=true;
q.push({0,st});
for(int i=1;i<=m;i++)
{
int f,t,v;
cin>>f>>t>>v;
s[f].push_back({t,v});
}
dijkstra();
for(int i=1;i<=n;i++)
{
if(dis[i]!=0x3f3f3f3f)
cout<<dis[i]<<' ';
else
cout<<"2147483647"<<' ';
}
cout<<endl;
return 0;
}
四.KMP
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=20000005;
char str1[MAXN],str2[MAXN];
int z[MAXN],Z[MAXN];
int n,m;
void getext(){
int l=0,r=0;
z[1]=m;
for(int i=2;i<=m;i++){
if(i>r){
while(str2[z[i]+1]==str2[i+z[i]])
z[i]++;
l=i,r=i+z[i]-1;
}
else if(z[i-l+1]<r-i+1) z[i]=z[i-l+1];
else{
z[i]=r-i;
while(str2[z[i]+1]==str2[i+z[i]])
z[i]++;
l=i,r=i+z[i]-1;
}
}
}
signed main(){
scanf("%s%s",str1+1,str2+1);
n=strlen(str1+1),m=strlen(str2+1);
getext();
int res=z[1]+1;
for(int i=2;i<=m;i++) res^=i*(z[i]+1);
cout<<res<<endl;
int l=0,r=0;
for(int i=1;i<=n;i++){
if(i>r){
while(1+Z[i]<=m&&i+Z[i]<=n&&str2[Z[i]+1]==str1[i+Z[i]])
Z[i]++;
l=i,r=i+Z[i]-1;
}
else if(z[i-l+1]<r-i+1) Z[i]=z[i-l+1];
else{
Z[i]=r-i+1;
while(1+Z[i]<=m&&i+Z[i]<=n&&str2[Z[i]+1]==str1[i+Z[i]])
Z[i]++;
l=i,r=i+Z[i]-1;
}
}
res=Z[1]+1;
for(int i=2;i<=n;i++) res^=i*(Z[i]+1);
cout<<res<<endl;
return 0;
}
五.AC自动机
#include<bits/stdc++.h>
using namespace std;
const int MAXN=800005;
int Trie[MAXN][27],tot,End[MAXN];
void Insert(string s,int up){
int u=0,len=s.size();
for(int i=0;i<len;i++){
int c=s[i]-'a';
if(!Trie[u][c])
Trie[u][c]=++tot;
u=Trie[u][c];
}
End[u]=up;
}
int n,fail[MAXN];
string a[MAXN],b;
void buildfail(){
queue<int> q;
for(int i=0;i<26;i++)
if(Trie[0][i]){
q.push(Trie[0][i]);
fail[Trie[0][i]]=0;
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;i++){
if(Trie[u][i])
fail[Trie[u][i]]=Trie[fail[u]][i],q.push(Trie[u][i]);
else Trie[u][i]=Trie[fail[u]][i];
}
}
}
int ans[MAXN];
void query(){
int len=b.size(),u;
for(int i=0,u=0;i<len;i++){
u=Trie[u][b[i]-'a'];
for(int j=u;j;j=fail[j]) ans[End[j]]++;
}
return;
}
int main(){
cin>>n;
while(n!=0){
for(int i=0;i<=tot;i++)
for(int j=0;j<=26;j++)
Trie[i][j]=0;
for(int i=1;i<=n;i++){
cin>>a[i];
Insert(a[i],i);
}
memset(fail,0xcf,sizeof(fail));
fail[0]=0;
buildfail();
cin>>b;
query();
int ma=INT_MIN;
vector<int> maans;
for(int i=1;i<=n;i++)
if(ans[i]>ma){
ma=ans[i];
maans.clear();
maans.push_back(i);
}
else if(ans[i]==ma){
maans.push_back(i);
}
cout<<ma<<endl;
for(int i=0;i<maans.size();i++)
cout<<a[maans[i]]<<endl;
for(int i=1;i<=n;i++) ans[i]=0;
cin>>n;
}
return 0;
}
六.混合背包
复制代码到粘帖板
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=10010;
int n,m,v[MAXN],w[MAXN],tot;
bool flag[MAXN];
ll ans,f[MAXN];
int main(){
memset(f,0xcf,sizeof(f));
f[0]=0;
cin>>m>>n;
for(int i=1;i<=n;i++){
int V,W,cnt;
cin>>V>>W>>cnt;
if(cnt){
for(int j=1;j<cnt;j*=2){
v[++tot]=V*j;
w[tot]=W*j;
flag[tot]=1;
cnt-=j;
}
if(cnt){
v[++tot]=V*cnt;
w[tot]=W*cnt;
flag[tot]=1;
}
}
else{
v[++tot]=V;
w[tot]=W;
flag[tot]=0;
}
}
for(int i=1;i<=tot;i++)
if(flag[i])
for(int j=m;j>=v[i];j--)
ans=max(ans,f[j]=max(f[j],f[j-v[i]]+w[i]));
else
for(int j=v[i];j<=m;j++)
ans=max(ans,f[j]=max(f[j],f[j-v[i]]+w[i]));
cout<<ans<<endl;
return 0;
}
七.状压DP
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
ll f[13][103][1<<10];
vector<int> allst,head[1<<10];
int cnt[1<<10];
bool check(int s){
for(int i=0;i<n;i++) if((s>>i&1)&&(s>>i+1&1)) return false;
return true;
}
int Count(int s){
int res=0;
for(int i=0;i<n;i++){
if(s>>i&1)
res++;
}
return res;
}
int main(){
cin>>n>>m;
for(int i=0;i<(1<<n);i++)
if(check(i)){
allst.push_back(i);;
cnt[i]=Count(i);
}
for(int i=0;i<allst.size();i++)
for(int j=0;j<allst.size();j++)
if((allst[i]&allst[j])==0&&check(allst[i]|allst[j]))
head[i].push_back(j);
f[0][0][0]=1;
for(int i=1;i<=n+1;i++)
for(int j=0;j<=m;j++)
for(int a=0;a<allst.size();a++)
for(int b=0;b<head[a].size();b++)
if(cnt[allst[a]]<=j)
f[i][j][allst[a]]+=f[i-1][j-cnt[allst[a]]][allst[head[a][b]]];
cout<<f[n+1][m][0]<<endl;
return 0;
}
八.EXGCD
int ex_gcd(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return a;
}
int d=ex_gcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return d;
}
九.EXCRT
ll EXCRT(){
for(int i=2;i<=n;i++){
ll a1=a[i-1],a2=a[i],m1=m[i-1],m2=m[i],c=(a2-a1%m2+m2)%m2;
ll M=lcm(m1,m2);
ll x,y;
ll d=exgcd(m1,m2,x,y);
ll p=Mul(x,c/d,m2);
a[i]=a1+m1*p;
a[i]=(a[i]%M+M)%M,m[i]=M;
}
return a[n];
}
十.模拟退火
#include<bits/stdc++.h>
using namespace std;
double T=90000,Down=0.998,eps=1e-14;
/*
T++,时间++,精度++;
Down++,时间++,精度++;
eps--,时间++,精度++;
*/
//样例函数:y=x^4+x^3-3*x^2-x 极点:(-1.63,-3.61) (1,-2)
double f(int x){
return x*x*x*x+x*x*x-3.0*x-x;
}
int random(int x){
return rand()*rand()%x;
}
int main(){
//x -100~100
srand(time(NULL));
double x=0,F;
x=100-random(200);
F=f(x);
while(T>eps){
// cout<<x<<' '<<T<<endl;
double nx=101;
while(nx>100||nx<-100){
double dx=(2*random(100)-100)*T;
nx=x+dx;//保证落到值域内
}
double Fn=f(nx);
if(Fn<F) x=nx,F=Fn;//如果更优则替换
else{
double chance=exp(-abs(Fn-F)/T);//如果不能满足,也有一定的概率替换
if(rand()<RAND_MAX*chance) x=nx,F=Fn;//防止小数运算
}
T*=Down;//温度下降
}
cout<<x<<' '<<F<<endl;
return 0;
}