板子们(不定时更新)
板子们
早期写代码大括号竟然换行,QAQ,我都没法原谅我自己。
emmm,把我目前能想到的,会的,全写上了。
如果再想到还会补的。
目录
数论
exgcd
#include<iostream>
using namespace std ;
int a,b,x,y;
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;y=0;
return a;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
int main(){
cin>>a>>b;
exgcd(a,b,x,y);
cout<<((x%b)+b)%b;
return 0;
}
快速幂(取模)
#include<iostream>
#define ll long long
using namespace std;
ll ksm(ll a,ll b,ll p){
ll ans=1;
while(b!=0){
if(b&1){
ans=ans*a%p;
}
a=a*a%p;
b>>=1;
}
return ans;
}
ll b,a,ans,p;
int main(){
cin>>a>>b>>p;
ans=ksm(a,b,p);
ans%=p;//好习惯
cout<<a<<'^'<<b<<" mod "<<p<<'='<<ans;
}
就是0次方%1的情况,要最后在%一次,不然会被卡
(像我一直有这种好习惯)
CRT
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n;
ll N=1;
ll a[20],b[20];
ll ans=0;
ll qaq(ll a,ll b,ll mod){
ll ans=0;
while(b>0)
{
if(b&1) ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){x=1,y=0;return;}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
void CRT()
{
ll x,y;
for(int i=1;i<=n;++i){
ll tp=N/b[i];
exgcd(tp,b[i],x,y);
x=(x%b[i]+b[i])%b[i];
ans=(ans+qaq(qaq(tp,x,N),a[i],N))%N;
}
}
int main(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
}
for(int i=1;i<=n;++i){
cin>>b[i];
N*=b[i];
a[i]=((a[i]%b[i])+b[i])%b[i];
}
CRT();
cout<<((ans%N)+N)%N;
return 0;
}
裴蜀定理
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int ans=0;
int a;
inline void read(int &x){
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9'){ x=x*10+s-'0';s=getchar();}
x*=f;
}
inline int gcd(int a,int b){
if(b==0) return a;
return gcd(b,a%b);
}
int main(){
read(n);
for(int i=1;i<=n;i++){
read(a);
if(a<0) a=-a;
ans=gcd(ans,a);
}
cout<<ans<<endl;
}
有理数取余
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
/*----------------HUI----------------*/
inline void read(int &x){
x=0;int f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=(x*10+s-'0')%19260817;s=getchar();}
x*=f;
}
inline int ksm(int x,int y=19260815){
int ans=1;
while(y){
if(y&1) ans=ans*x%19260817;
x=x*x%19260817;
y>>=1;
}
return ans;
}
int a,b;
signed main(){
read(a);read(b);
int sum=(a*ksm(b))%19260817;
if(sum==0){
cout<<"Angry!"<<endl;
}
else{
cout<<sum<<endl;
}
return 0;
}
乘法逆元
快速幂:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n,p;
ll ksm (ll a,ll b=p-2){
ll ans=1;
while(b>0){
if(b&1){
ans=ans*a%p;
}
a=a*a%p;
b>>=1;
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>p;
for(int i=1;i<=n;i++) {
cout<<ksm(i)<<endl;
}
return 0;
}
拓展欧几里德
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n,p;
ll x,y;
void exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1,y=0;
return;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>p;
for(int i=1;i<=n;i++){
exgcd(i,p,x,y);
cout<<((x%p)+p)%p<<endl;
}
return 0;
}
线性递推
(没事就别用cin,cout,我线性递推因此T3个点)
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n,p;
ll inv[3050500];
int main(){
cin>>n>>p;
inv[1]=1;
printf("1\n");
for(int i=2;i<=n;i++){
inv[i]=(p-p/i)*inv[p%i]%p;
printf("%lld\n",inv[i]);
}
return 0;
}
卢卡斯定理
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define ll long long
ll t,n,m,p;
ll a[100007],b[100007];
ll lucas(int x,int y)
{
if(x<y) return 0;
else if(x<p) return b[x]*a[y]*a[x-y]%p;
else return lucas(x/p,y/p)*lucas(x%p,y%p)%p;
}
int main()
{
scanf("%lld",&t);
while(t)
{
scanf("%lld%lld%lld",&n,&m,&p);
a[0]=a[1]=b[0]=b[1]=1;
for(int i=2;i<=n+m;i++) b[i]=b[i-1]*i%p;
for(int i=2;i<=n+m;i++) a[i]=(p-p/i)*a[p%i]%p;
for(int i=2;i<=n+m;i++) a[i]=a[i-1]*a[i]%p;
printf("%lld\n",lucas(n+m,m));
t--;
}
return 0;
}
欧拉筛全家桶(prime+phi+d+sd)
const int N=1e5+5;
bool mark[N];
int prim[N],d[N],num[N];
long long sd[N],sp[N];
int cnt;
void initial()
{
cnt=0;
d[1]=1;
sd[1]=1;
for(int i=2;i<N;++i)
{
if (!mark[i])
{
prim[++tot]=i;
phi[i]=i-1;
sd[i]=i+1;
sp[i]=i+1;
num[i]=1;
d[i]=2;
}
for(int j=0;j<cnt&&i*prim[j]<N;++j)
{
mark[i*prim[j]]=1;
if (!(i%prim[j]))
{
num[i*prim[j]]=num[i]+1;
d[i*prim[j]]=d[i]/(num[i]+1)*(num[i*prim[j]]+1);
sp[i*prim[j]]=sp[i]*prim[j]+1;
sd[i*prim[j]]=sd[i]/sp[i]*sp[i*prim[j]];
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
d[i*prim[j]]=d[i]*d[prim[j]];
num[i*prim[j]]=1;
sd[i*prim[j]]=sd[i]*sd[prim[j]];
sp[i*prim[j]]=1+prim[j];
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
矩阵加速
#include<cstdio>
#include<iostream>
#include <cstring>
using namespace std;
#define ll long long
#define il inline
#define r register
#define mod 1000000007
ll t;
ll n;
struct node
{
ll ju[5][5];
}chu,e,D;
node multiply(node a,node b)
{
node t;
for(r ll i=1;i<=3;i++)
for(r ll j=1;j<=3;j++)
t.ju[i][j]=0;
for(r ll i=1;i<=3;i++)
for(r ll j=1;j<=3;j++)
for(r ll k=1;k<=3;k++)
{
t.ju[i][j]+=(a.ju[i][k]%mod)*(b.ju[k][j]%mod)%mod;
t.ju[i][j]%=mod;
}
return t;
}
node ksm(node x,ll y)
{
node re=D;
while(y)
{
if(y&1)
re=multiply(re,x);
x=multiply(x,x);
y>>=1;
}
return re;
}
int main()
{
scanf("%lld",&t);
chu.ju[1][1]=1;
chu.ju[1][2]=1;
chu.ju[1][3]=1;
e.ju[1][3]=1;
e.ju[2][1]=1;
e.ju[3][2]=1;
e.ju[3][3]=1;
for(r ll i=1;i<=3;i++)
D.ju[i][i]=1;
while(t--)
{
scanf("%lld",&n);
if(n<=3)
{
printf("1\n");
continue;
}
node ans=multiply(chu,ksm(e,n-3));
printf("%lld\n",ans.ju[1][3]%mod);
}
return 0;
}
矩阵快速幂
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
#define IL inline
#define R register
const int mod=1e9+7;
using namespace std;
int n,k;
struct node{
int ju[120][120];
node(){
memset(ju,0,sizeof ju);
}
friend node operator * (const node &a,const node &b)
{
node t;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++){
(t.ju[i][j]+=a.ju[i][k]*b.ju[k][j])%=mod;
}
return t;
}
void e()
{
memset(ju,0,sizeof ju);
for(int i=1;i<=n;i++)
{
ju[i][i]=1;
}
}
void out(){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
printf("%d%c",ju[i][j],j==n?'\n':' ');
}
}
}chu,E;
node ksm(node x,int y){
E.e();
while(y)
{
if(y&1)
E=E*x;
x=x*x;
y>>=1;
}
return E;
}
signed main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>chu.ju[i][j];
(ksm(chu,k)).out();
return 0;
}
nim游戏
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
#define ll long long
#define IL inline
#define R register
using namespace std;
int main(){
int T;
int n;
int x;
cin>>T;
while(T--){
cin>>n;
int ans=0;
for(int i=1;i<=n;i++){
cin>>x;
ans=ans^x;
}
if(ans){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
return 0;
}
图论
最小生成树
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,ans=0;
int fa[105050];
struct node{
int u,v,w;
}qwq[205050];
inline void read(int &x){
x=0;int f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
inline bool cmp(node a,node b){
return a.w<b.w;
}
inline int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
int main(){
read(n);read(m);
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
read(qwq[i].u);read(qwq[i].v);read(qwq[i].w);
}
sort(qwq+1,qwq+1+m,cmp);
for(int i=1;i<=m;i++){
if(find(qwq[i].u)!=find(qwq[i].v)){
fa[find(qwq[i].u)]=find(qwq[i].v);
ans+=qwq[i].w;
}
}
cout<<ans<<endl;
return 0;
}
二分图
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int ans=0;
int x,y;
int n,m,e;
struct node{
int u;
int v;
}qwq[305000];
int head[305050];
int tot=0;
bool vis[305050];
int to[305050];
inline void add(int x,int y){
qwq[++tot].u=head[x];
qwq[tot].v=y;
head[x]=tot;
}
inline bool find(int x){
for(int i=head[x];i;i=qwq[i].u){
int v=qwq[i].v;
if(vis[v]==0){
vis[v]=1;
if(to[v]==0||find(to[v])==1){
to[v]=x;
return 1;
}
}
}
return 0;
}
int main(){
cin>>n>>m>>e;
for(int i=1;i<=e;i++){
cin>>x>>y;
if(y>m||x>n){
continue;
}
add(x,y);
}
for(int i=1;i<=n;i++){
memset(vis,0,sizeof vis);
ans+=find(i);
}
cout<<ans<<endl;
}
spfa判负环(你就当是差分约束也行)
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
/*----------------HUI----------------*/
int T;
int n,m;
int head[105050],tot=0;
int toto[105050];
int dis[105050];
int vis[105050];
int x,y,z;
struct node{
int u,v,w;
}qwq[105050];
queue<int>q;
inline void add(int x,int y,int z){
qwq[++tot].u=head[x];
qwq[tot].v=y;
qwq[tot].w=z;
head[x]=tot;
}
inline void clear(){
tot=0;
memset(head,0,sizeof head);
memset(toto,0,sizeof toto);
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
}
inline bool spfa(int x){
q.push(x);
dis[x]=0;
vis[x]=1;
toto[x]++;
while(!q.empty()){
int u=q.front();q.pop();vis[u]=0;
for(int i=head[u];i;i=qwq[i].u){
int v=qwq[i].v;
if(dis[v]>dis[u]+qwq[i].w){
dis[v]=dis[u]+qwq[i].w;
if(vis[v]==0){
vis[v]=1;
toto[v]++;
if(toto[v]>n){
return 1;
}
q.push(v);
}
}
}
}
return 0;
}
int main(){
cin>>T;
while(T--){
clear();
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
if(z<0){
add(x,y,z);
}
else{
add(x,y,z);
add(y,x,z);
}
}
if(spfa(1)){
cout<<"YE5"<<endl;
}
else{
cout<<"N0"<<endl;
}
}
return 0;
}
2-sat
#include<cmath>
#include<string>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define IL inline
#define R register
using namespace std;
inline void read(int &x){
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x*=f;
}
/*名为DracoM*/
int n,dfn[5050500],low[5050500],belong[5050500],stk[5050500];
int top;
int a;
int m;
int b,c,d;
int f,e;
int head[5050500];
int tot=0;
int idx,cnt,ins[5050500];
int ans=0;
bool vis[5050500];
struct node{
int u,v;
}qwq[5050500];
inline void add(int x,int y){
qwq[++tot].u=head[x];
qwq[tot].v=y;
head[x]=tot;
}
inline void tarjan(int x){
dfn[x]=low[x]=++idx;
stk[++top]=x;vis[x]=true;
for(int i=head[x];i;i=qwq[i].u){
if(!dfn[qwq[i].v]){
tarjan(qwq[i].v);
low[x]=min(low[x],low[qwq[i].v]);
}
else if (vis[qwq[i].v]) low[x]=min(low[x],dfn[qwq[i].v]);
}
if(dfn[x]==low[x]){
cnt++;
int now=-1;
while(x!=now)
{
now=stk[top--];
belong[now]=cnt;
vis[now]=false;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a>>b>>c>>d;
int e=b^1;
int f=d^1;
add(a+e*n,c+d*n);
add(c+f*n,a+b*n);
}
for(int i=1;i<=(n<<1);i++)
{
if(dfn[i])continue;
tarjan(i);
}
for(int i=1;i<=n;i++){
if(belong[i+n]==belong[i]){
cout<<"IMPOSSIBLE"<<endl;
return 0;
}
}
cout<<"POSSIBLE"<<endl;
for(int i=1;i<=n;i++)
printf("%d ",belong[i]>belong[i+n]);
return 0;
}
LCA
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxlog = 20;
const int maxn = 550000;
int n, m, s;
int root;
int fa[maxn][maxlog];
int deep[maxn];
int head[maxn];
int cnt;
struct Edge{
int next;
int to;
}e[2*maxn];
void add(int u, int v){
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
void dfs(int u, int p, int d){
fa[u][0] = p;
deep[u] = d;
for(int i = head[u]; i != -1; i = e[i].next)
if(e[i].to != p) dfs(e[i].to, u, d+1);
}
void init(){
dfs (root, -1, 0);
for(int k = 0; k + 1 < maxlog; k++)
{
for(int v = 1; v <= n; v++)
if(fa[v][k] < 0) fa[v][k+1] = -1;
else fa[v][k+1] = fa[fa[v][k]][k];
}
}
int lca(int u, int v)
{
if(deep[u] > deep[v]) swap(u, v);
for(int k = 0; k < maxlog; k++)
{
if(deep[v] == deep[u]) break;
if((deep[v] - deep[u]) >> k & 1)
{
v = fa[v][k];
}
}
if(u == v) return u;
for(int k = maxlog - 1; k >= 0; k--)
{
if(fa[v][k] != fa[u][k])
{
u = fa[u][k];
v = fa[v][k];
}
}
return fa[u][0];
}
int main(){
memset(head,-1,sizeof(head));
int a,b;
scanf("%d%d%d",&n,&m,&root);
for(int i = 1; i < n; i++){
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
init();
for(int i = 1; i <= m; i++){
int u,v,a;
scanf("%d%d",&u,&v);
a = lca(u,v);
printf("%d\n",a);
}
return 0;
}
DIJ求最短路
#include<bits/stdc++.h>
#define int long long
using namespace std;
int dis[205050];
bool vis[205050];
struct node{
int u,v,w;
}qwq[205050];
int tot=0;
int head[205050];
int n,m,s;
void add(int x,int y,int z)
{
qwq[++tot].u=head[x];
qwq[tot].v=y;
qwq[tot].w=z;
head[x]=tot;
}
priority_queue<pair<int,int>,vector<pair<int,int> >, greater<pair<int ,int > > >q;
void dij(int s){
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
q.push(make_pair(0,s));
dis[s]=0;
while(!q.empty()){
pair<int,int> tp=q.top();
q.pop();
if(vis[tp.second]==1){
continue;
}
vis[tp.second]=1;
for(int i=head[tp.second];i;i=qwq[i].u){
int v=qwq[i].v;
if(dis[v]>dis[tp.second]+qwq[i].w){
dis[v]=dis[tp.second]+qwq[i].w;
q.push(make_pair(dis[v],v));
}
}
}
}
signed main(){
cin>>n>>m>>s;
int x,y,z;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
add(x,y,z);
}
dij(s);
for(int i=1;i<=n;i++){
cout<<dis[i]<<' ';
}
return 0;
}
倍增Floyd
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll vis[20500];
ll w[2050][2050];
ll n,tot,m,s,t;
struct node{
ll f[205][205];
node(){memset(f,0x3f,sizeof f);}
}ans;
node mul(node a,node b){
node re;
for(ll k=1;k<=tot;k++)
for(ll i=1;i<=tot;i++)
for(ll j=1;j<=tot;j++)
if(re.f[i][j]>a.f[i][k]+b.f[k][j])
re.f[i][j]=a.f[i][k]+b.f[k][j];
return re;
}
ll ksm(ll k){
node re;
for(ll i=1;i<=tot;i++)
re.f[i][i]=0;
while(k){
if(k&1) re=mul(re,ans);
ans=mul(ans,ans);
k>>=1;
}
return re.f[vis[s]][vis[t]];
}
int main(){
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
for(ll i=1;i<=m;i++){
ll c,a,b;
scanf("%lld%lld%lld",&c,&a,&b);
if(!vis[a]) vis[a]=++tot;
if(!vis[b]) vis[b]=++tot;
ans.f[vis[a]][vis[b]]=ans.f[vis[b]][vis[a]]=min(ans.f[vis[a]][vis[b]],c);
}
printf("%lld\n",ksm(n));
return 0;
}
次短路
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
using namespace std;
#define LL long long
LL n,m;
struct node{
LL to,nxt,dis;
}e[300500];
LL head[100020],tot;
LL dis1[100020],dis2[100020];
void add(LL u,LL v,LL val){
e[++tot].nxt=head[u];
e[tot].to=v;
e[tot].dis=val;
head[u]=tot;
}
typedef pair<LL,LL> P;
priority_queue<P,vector<P>,greater<P> > q;
void DIJ(){
memset(dis1,0x3f,sizeof dis1);
memset(dis2,0x3f,sizeof dis2);
dis1[1]=0;
q.push(make_pair(0,1));
while(!q.empty()){
P u=q.top();
q.pop();
LL x=u.second,d=u.first;
if(dis2[x]<d)continue;
for(LL i=head[x];i;i=e[i].nxt){
LL d2=d+e[i].dis,v=e[i].to;
if(dis1[v]>d2){
dis2[v]=dis1[v];
swap(dis1[v],d2);
q.push(make_pair(dis1[v],v));
}
if(dis2[v]>d2&&dis1[v]<d2){
dis2[v]=d2;
q.push(make_pair(dis2[v],v));
}
}
}
}
int main(){
scanf("%lld%lld",&n,&m);
for(LL i=1;i<=m;i++){
LL x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
DIJ();
printf("%lld\n",dis2[n]);
return 0;
}
分层图最短路
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
#define mp make_pair
#define S second
#define F first
using namespace std;
int x,y,z;
int s,t,n,m,k;
struct node{
int u,v,w;
}qwq[205050];
int tot=0,head[205050];
int dis[205050][21],vis[205050][21];
void add(int x,int y,int z){
qwq[++tot].u=head[x];
qwq[tot].v=y;
qwq[tot].w=z;
head[x]=tot;
}
void Dijkstra(){
memset(dis,0x3f,sizeof dis);
priority_queue<pair<int ,pair<int ,int > > > pq;
pair<int,int> u;
int v;
dis[s][0]=0;
pq.push(mp(0,mp(s,0)));
while(!pq.empty()){
u=pq.top().S;
pq.pop();
if(vis[u.F][u.S]){
continue;
}
vis[u.F][u.S]=1;
for(int i=head[u.F];i;i=qwq[i].u){
v=qwq[i].v;
if(dis[v][u.S]>dis[u.F][u.S]+qwq[i].w){
dis[v][u.S]=dis[u.F][u.S]+qwq[i].w;
pq.push(mp(-dis[v][u.S],mp(v,u.S)));
}
if(u.S+1<=k&&dis[v][u.S+1]>dis[u.F][u.S]){
dis[v][u.S+1]=dis[u.F][u.S];
pq.push(mp(-dis[v][u.S+1],mp(v,u.S+1)));
}
}
}
}
int ans=0x3f3f3f3f;
signed main(){
cin>>n>>m>>k;
cin>>s>>t;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
add(x,y,z);
add(y,x,z);
}
Dijkstra();
cout<<dis[t][k]<<endl;
// cout<<ans<<endl;
}
割点
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int x,y;
struct node{
int u,v;
}qwq[1050050];
int tot=0,head[1050050];
int dfn[1050050],low[1005050];
bool ans[1050050];
int idx=0;
void add(int x,int y){
qwq[++tot].u=head[x];
qwq[tot].v=y;
head[x]=tot;
}
void tarjan(int x,int fa){
int sum=0;
dfn[x]=low[x]=++idx;
for(int i=head[x];i;i=qwq[i].u){
int v=qwq[i].v;
if(!dfn[v]){
tarjan(v,fa);
if(low[v]>=dfn[x]&&x!=fa){
ans[x]=1;
}
if(x==fa){
sum++;
}
low[x]=min(low[x],low[v]);
}
low[x]=min(low[x],dfn[v]);
}
if(x==fa&&sum>1) ans[x]=1;
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y;
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++){
if(dfn[i]==0){
tarjan(i,i);
}
}
int cntt=0;
for(int i=1;i<=n;i++){
if(ans[i])
cntt++;
}
printf("%d\n",cntt);
for(int i=1;i<=n;i++){
if(ans[i])
printf("%d ",i);
}
return 0;
}
缩点
#include<cmath>
#include<queue>
#include<string>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define IL inline
#define R register
using namespace std;
inline void read(int &x){
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x*=f;
}
/*名为DracoM*/
queue<int>q;
int n,m;
int x,y;
int top;
int cnt;
int idx;
int ans;
int val[105050];
int dfn[105050];
int dis[105050];
int low[105050];
int stk[105050];
int val2[105050];
bool vis[105050];
int belong[105050];
int head[105050],tot=0;
int head1[105050];
struct node{
int u,v;
} qwq[105050],qaq[105050];
inline void add (int x,int y){
qwq[++tot].u=head[x];
qwq[tot].v=y;
head[x]=tot;
}
inline void add1(int x,int y){
tot++;
qaq[tot].v=y;
qaq[tot].u=head1[x];
head1[x]=tot;
}
IL void spfa(int x)
{
memset(vis ,0 ,sizeof vis);
for(int i=1;i<=n;i++)
{
dis[i]=-2147483644;
}
q.push(x);
dis[x]=val2[x];
vis[x]=1;
while(!q.empty()){
int tp=q.front();
q.pop();
vis[tp]=0;
for(int i=head1[tp];i;i=qaq[i].u){
int v=qaq[i].v;
if(dis[v]<dis[tp]+val2[v])
{
dis[v]=dis[tp]+val2[v];
if(vis[v]==0){
vis[v]=1;
q.push(v);
}
}
}
}
for(int i=1;i<=cnt;i++) ans=max(ans,dis[i]);
}
inline void tarjan(int x){
dfn[x]=low[x]=++idx;
stk[++top]=x;vis[x]=true;
for(int i=head[x];i;i=qwq[i].u){
if(!dfn[qwq[i].v]){
tarjan(qwq[i].v);
low[x]=min(low[x],low[qwq[i].v]);
}
else if(vis[qwq[i].v]) low[x]=min(low[x],dfn[qwq[i].v]);
}
if(dfn[x]==low[x]){
cnt++;
int now=-1;
while(x!=now){
now=stk[top--];
val2[cnt]+=val[now];
belong[now]=cnt;
vis[now]=false;
}
}
}
inline void shink_point(){
tot=0;int t;
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=qwq[j].u)
{
t=qwq[j].v;
if(belong[i]!=belong[t])
add1(belong[i],belong[t]);
}
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>val[i];
}
for(int i=1;i<=m;i++){
cin>>x>>y;
add(x,y);
}
for(int i=1;i<=n;i++){
if(dfn[i]){
continue;
}
tarjan(i);
}
shink_point();
for(int i=1;i<=cnt;i++){
spfa(i);
}
cout<<ans<<endl;
return 0;
}
数据结构
手写栈
/*主要为了单调栈准备的*/
struct node{
int st[1005050];
int tp;
inline void pop() {tp--;}
inline void push(int x) {st[++tp]=x;}
inline bool empty() {return !tp;}
inline int top() {return st[tp];}
}s;
堆
#include<queue>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;
int n,x,o;
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>o;
if(o==1){
cin>>x;
q.push(x);
}
else if(o==2){
cout<<q.top()<<endl;
}
else{
q.pop();
}
}
return 0;
}
ST表
#include<cmath>
#include<cstdio>
#include<algorithm>
#define R register
using namespace std;
inline void read(int &x){
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,m,a[105050][30];
int x,y;
inline int query(int x,int y){
int l=log2(y-x+1);
return max(a[x][l],a[y-(1<<l)+1][l]);
}
int main()
{
read(n);read(m);
for(R int i=1;i<=n;i++){
read(a[i][0]);
}
for(R int j=1;j<=18;j++)
for(R int i=1;i+(1<<j)-1<=n;i++){
a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]);
}
for(R int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
print(query(x,y));
printf("\n");
}
}
树状数组1
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
/*----------------HUI----------------*/
int n,m,x,y,z;
int sz[505050];
inline int lowbit(int x){
return x&(-x);
}
inline void add(int x,int y){
for(int i=x;i<=n
;i+=lowbit(i)){
sz[i]+=y;
}
}
inline int sum(int x){
int ans=0;
for(int i=x;i>0;i-=lowbit(i)){
ans+=sz[i];
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>x;
add(i,x);
}
while(m--){
cin>>x;
if(x==1){
cin>>y>>z;
add(y,z);
}
else{
cin>>y>>z;
cout<<sum(z)-sum(y-1)<<endl;
}
}
return 0;
}
树状数组2
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
int n;
int m;
int ci[500010];
int a,b,c,d;
int ai[500010];
int cf;
int lowbit(int x)
{
return x&(-x);
}
int getsum(int x)
{
int ans=0;
for (int i = x; i > 0; i-= lowbit(i))
{
/* code */
ans+=ci[i];
}
return ans;
}
void add(int x,int y)
{
for (int i = x; i <= n; i+=lowbit(i))
{
/* code */
ci[i]+=y;
}
}
signed main()
{
scanf("%lld%lld",&n,&m);
ai[0]=0;
for (int i = 1; i <= n; ++i)
{
/* code */
scanf("%lld",&ai[i]);
cf=ai[i]-ai[i-1];
add(i,cf);
}
while ( m-- )
{
scanf("%lld",&a);
if(a==1)
{
scanf("%lld%lld%lld",&b,&c,&d);
add(b,d);
add(c+1,-d);
}
else if(a==2)
{
scanf("%lld",&b);
printf("%lld\n",getsum(b));
}
}
return 0;
}
冰茶姬
#include<iostream>
using namespace std;
int n,m;
int x,y,z;
int fa[205050];
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
cin>>z>>x>>y;
if(z==1){
fa[find(x)]=find(fa[y]);
}
else{
if(find(x)==find(y)){
cout<<"Y"<<endl;
}
else cout<<'N'<<endl;
}
}
}
带权冰茶姬
int x,y;
int dis[505050];int siz[505050];
int n;char s;int fa[505050];
inline int find(int x){
if(x!=fa[x])
{
int f=fa[x];
fa[x]=find(fa[x]);
dis[x]+=dis[f];
}
return fa[x];
}
int main(){
cin>>n;
for(int i=1;i<=30000;i++){
siz[i]=1;
fa[i]=i;
}
for(int i=1;i<=n;i++){
cin>>s;
if(s=='M'){
cin>>x>>y;
x=find(x),y=find(y);
dis[x]=siz[y];
fa[x]=y;
siz[y]+=siz[x];
}
else{
cin>>x>>y;
if(find(x)!=find(y))
cout<<-1<<endl;
else
cout<<abs(dis[x]-dis[y])-1<<endl;
}
}
return 0;
}
线段树1
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define int long long
#define ls o<<1
#define rs o<<1|1
using namespace std;
int n;
int m;
int a[405050];
int tg[405050];
int b,c,d,e,f;
inline void up(int o){
a[o]=a[ls]+a[rs];
}
inline void build(int o,int l,int r){
if(l==r){
cin>>a[o];
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
up(o);
}
inline void down(int o,int l,int r){
if(tg[o]){
tg[ls]+=tg[o];
tg[rs]+=tg[o];
int mid=(l+r)>>1;
a[ls]+=(mid-l+1)*tg[o];
a[rs]+=(r-mid)*tg[o];
tg[o]=0;
}
}
inline void change(int o,int l,int r,int x,int y,int z){
if(x<=l and y>=r)
{
a[o]+=(r-l+1)*z;
tg[o]+=z;
return;
}
down(o,l,r);
int mid=(l+r)>>1;
if(x<=mid) change(ls,l,mid,x,y,z);
if(y>mid)change(rs,mid+1,r,x,y,z);
up(o);
}
inline int query(int o,int l,int r,int x,int y){
if(l>=x and r<=y){
return a[o];
}
down(o,l,r);int res=0;
int mid=(l+r)>>1;
if(x<=mid) res+=query(ls,l,mid,x,y);
if(y>mid) res+=query(rs,mid+1,r,x,y);
return res;
}
signed main(){
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>b;
if(b==1){
cin>>c>>d>>e;
change(1,1,n,c,d,e);
}
else{
cin>>c>>d;
cout<<query(1,1,n,c,d)<<endl;
}
}
return 0;
}
线段树2
#include<cstdio>
#include<iostream>
using namespace std;
#define II long long
#define mod 100500
#define QWQ ((mod<<2)+5)
#define LS(x) (x<<1)
#define RS(x) ((x<<1)|1)
#define M(x,y) ((x+y)>>1)
#define R register
#define IL inline
II a[mod],st[QWQ],add[QWQ],mul[QWQ];
II n,m,p,flag;
IL void build(II now, II l, II r)
{
mul[now]=1;
add[now]=0;
if(l == r)
{
st[now] = a[l];
}
else
{
R II mid = M(l,r);
build(LS(now), l, mid);
build(RS(now), mid+1, r);
st[now] = st[LS(now)] + st[RS(now)];
}
st[now] %= p;
}
IL void push_down(R II now, R II l, R II r)
{
R II mid = M(l,r);
st[LS(now)] = (st[LS(now)]*mul[now]+(mid-l+1)*add[now])%p;
st[RS(now)] = (st[RS(now)]*mul[now]+(r-mid)*add[now])%p;
mul[LS(now)] = (mul[LS(now)]*mul[now])%p;
mul[RS(now)] = (mul[RS(now)]*mul[now])%p;
add[LS(now)] = (add[LS(now)]*mul[now]+add[now])%p;
add[RS(now)] = (add[RS(now)]*mul[now]+add[now])%p;
mul[now] = 1;
add[now] = 0;
return ;
}
IL void multiply(R II now,R II nowl,R II nowr,R II l,R II r,R II k)
{
if(nowr < l || nowl > r)
return ;
if(nowr <= r && nowl >= l)
{
st[now] = (st[now]*k)%p;
mul[now] = (mul[now]*k)%p;
add[now] = (add[now]*k)%p;
return ;
}
push_down(now, nowl, nowr);
R II mid = M(nowl,nowr);
multiply(LS(now),nowl,mid,l,r,k);
multiply(RS(now),mid+1,nowr,l,r,k);
st[now] = ( st[LS(now)] + st[RS(now)] )%p;
return;
}
IL void jia(R II now,R II nowl,R II nowr,R II l,R II r,R II k)
{
if(nowr < l || nowl > r)
return ;
if(nowr <= r && nowl >= l)
{
add[now] = (add[now]+k)%p;
st[now] = (st[now] + k*(nowr-nowl+1))%p;
return ;
}
push_down(now, nowl, nowr);
R II mid = M(nowl,nowr);
jia(LS(now),nowl,mid,l,r,k);
jia(RS(now),mid+1,nowr,l,r,k);
st[now] = ( st[LS(now)] + st[RS(now)] )%p;
return;
}
IL II query(R II now,R II nowl,R II nowr,R II l,R II r)
{
if(nowl > r || nowr < l)
return 0;
if(nowl >= l && nowr <=r)
return st[now];
push_down(now,nowl,nowr);
R II mid = M(nowl,nowr);
return (query(LS(now),nowl,mid,l,r)+query(RS(now),mid+1,nowr,l,r))%p;
}
int main()
{
scanf("%lld %lld %lld",&n,&m,&p);
for (R II i = 1; i <= n; i ++)
{
scanf("%lld",&a[i]);
}
build(1,1,n);
R II x,y,k;
while (m--)
{
scanf("%lld",&flag);
if(flag == 1)
{
scanf("%lld %lld %lld",&x,&y,&k);
multiply(1,1,n,x,y,k);
}
if(flag == 2)
{
scanf("%lld %lld %lld",&x,&y,&k);
jia(1,1,n,x,y,k);
}
if(flag == 3)
{
scanf("%lld %lld",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
}
return 0;
}
技巧与思想
对拍
color A
echo off
:loop
echo 已运行%a%次
set /a a+=1
shuju.exe
dou.exe
factory.exe
fc factory1.out factory2.out
if not errorlevel 1 goto loop
pause
测运行时间
#include<bits/stdc++.h>
using namespace std;
int main()
{
for(int i=1;i!=-1;i++)
{
system("data.exe");
int t=clock();
system("cannon.exe");
int b=clock();
cout<<"cannon的第"<<setw(6)<<rand()<<" "<<"次运行时间为: "<<b-t<<"ms"<<endl;
}
}
二维前缀和
qwq不想写了
快速排序
sort(qwq)
悬线法
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
using namespace std;
int n,m;
int ans1;
int ans2;
int a[2007][2007];
int l[2007][2007],r[2007][2007],u[2007][2007];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
l[i][j]=j;
r[i][j]=j;
u[i][j]=1;
}
}
for(int i=1;i<=n;i++){
for(int j=2;j<=m;j++){
if(a[i][j]!=a[i][j-1]){
l[i][j]=l[i][j-1];
}
}
}
for(int i=1;i<=n;i++){
for(int j=m-1;j>=1;j--){
if(a[i][j]!=a[i][j+1]){
r[i][j]=r[i][j+1];
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int lon;
if(i>1&&a[i][j]!=a[i-1][j]){
u[i][j]=u[i-1][j]+1;
r[i][j]=min(r[i-1][j],r[i][j]);
l[i][j]=max(l[i-1][j],l[i][j]);
}
int chang=r[i][j]-l[i][j]+1;
int shu=min(chang,u[i][j]);
ans1=max(ans1,shu*shu);
ans2=max(ans2,chang*u[i][j]);
}
}
cout<<ans1<<endl<<ans2<<endl;
return 0;
}
快读qaq
inline void read(int &x){
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
三分法
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define eps 1e-8
using namespace std;
int n;
double a[105];
double l,r;
inline double f(double x){
double ans=0;
for(int i=n;i>=0;i--){
ans=ans*x+a[i];
}
return ans;
}
int main(){
cin>>n>>l>>r;
for(int i=n;i>=0;i--){
cin>>a[i];
}
while(fabs(r-l)>=eps){
double mid=(r-l)/3.0;
double mid1=l+mid;
double mid2=r-mid;
if(f(mid1)<=f(mid2)){
l=mid1;
}
else r=mid2;
}
printf("%.5lf",l);
return 0;
}
最长公共子序列
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 1000007
using namespace std;
int n;
struct node{
int a;
int ord;
bool operator < (const node &b)const
{
return a<b.a;
}
}a[N];
int b[N],d[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].a);
a[i].ord=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
int k=b[i];
b[i]=a[k].ord;
}
int len=1;
memset(d,127/3,sizeof(d));
d[1]=b[1];
for(int i=1;i<=n;i++){
if(d[len]<b[i]){
d[++len]=b[i];
}
else {
int j=lower_bound(d+1,d+len+1,b[i])-d;
d[j]=b[i];
}
}
cout<<len<<endl;
return 0;
}
LIS
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
#define ll long long
#define IL inline
#define R register
using namespace std;
int n;
int a[105050];
int f[105050];
int g[105050];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int ans=1;
int ans2=1;
g[1]=f[1]=a[1];
for(int i=2;i<=n;i++){
if(a[i]>f[ans]){
f[++ans]=a[i];
}
else{
*upper_bound(f+1,f+1+ans,a[i])=a[i];
}
}
cout<<ans<<endl;
return 0;
}
计算几何
最小圆覆盖
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define cq(i,s,n) for(int i=s;i<=n;i++)
using namespace std;
const double eps=1e-12;
struct Point{
double x,y;
}a[500005];
Point o;
int n;
double ri;
inline void read(int &x){
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x*=f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9) print(x/10);
putchar(x%10+'0');
}
double dis(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void tt(Point p1,Point p2,Point p3){
double a,b,c,d,e,f;
a=p2.y-p1.y;
b=p3.y-p1.y;
c=p2.x-p1.x;
d=p3.x-p1.x;
f=p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y;
e=p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y;
o.x=(a*f-b*e)/(2*a*d-2*b*c);
o.y=(d*e-c*f)/(2*a*d-2*b*c);
ri=dis(o,p1);
}
int main(){
scanf("%d",&n);
cq(i,1,n){
scanf("%lf%lf",&a[i].x,&a[i].y);
}
random_shuffle(a+1,a+n+1);
o=a[1];ri=0;
for(int i=2;i<=n;i++){
if(dis(a[i],o)>ri+eps){
o=a[i];ri=0;
for(int j=1;j<=i-1;j++){
if(dis(o,a[j])>ri+eps){
o.x=(a[i].x+a[j].x)/2;
o.y=(a[i].y+a[j].y)/2;
ri=dis(o,a[j]);
for(int k=1;k<=j-1;k++){
if(dis(o,a[k])>ri+eps){
tt(a[i],a[j],a[k]);
}
}
}
}
}
}
printf("%.10lf\n%.10lf %.10lf",ri,o.x,o.y);
return 0;
}
二维凸包
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
struct node{
double x,y,p;//横纵坐标,极∠。
node(double x=0,double y=0):x(x),y(y){ }//?
friend node operator-(const node&a,const node&b){
return node(a.x-b.x,a.y-b.y);
}
friend double operator^(const node&a,const node&b){
return a.x*b.y-a.y*b.x;
}
double mod(){
return sqrt(x*x+y*y);
}//封装了三个函数,分别是距离,叉积和???
}a[10007];
bool cmp(const node&a,const node&b){
return a.p<b.p;
}
bool vis[10007];
int s[10007];//手写栈;
int top;//栈顶;
int minn=1;//最小值 ...定义成一。。。看下面。
int n;
double ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&a[i].x,&a[i].y);
if(a[minn].y>a[i].y||(a[minn].y==a[i].y&&a[minn].x>a[i].x))//左下
{
minn=i;
}
}
swap(a[1],a[minn]);
for(int i=2;i<=n;i++)
{
a[i].x-=a[1].x;
a[i].y-=a[1].y;
a[i].p=atan2(a[i].y,a[i].x);//极∠。//cmath自带
}
sort(a+2,a+1+n,cmp);
a[1].x=0;
a[1].y=0;
s[1]=1;
s[2]=2;
s[3]=3;
top=3;
for(int i=4;i<=n;i++)
{
while(top>2&&((a[s[top]]-a[s[top-1]])^(a[i]-a[s[top]]))<0)
top--;
s[++top]=i;
}
for(int i=1;i<top;i++)
{
ans+=(a[s[i+1]]-a[s[i]]).mod();
}
ans+=(a[n]-a[1]).mod();
printf("%.2lf",ans);
return 0;
}
字符串
字符串哈希
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#define mod 100000007
using namespace std;
struct node{
char a[1600];
int len;
int hash(){
int ans=0;
for(int i=1;i<=len;i++)
ans=(ans*10+a[i])%(int)mod;
return ans;
}
}b[10007];
int n;
set<int> p;
int ans=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%s",b[i].a+1);
b[i].len=strlen(b[i].a+1);
}
for(int i=1;i<=n;i++){
int ha=b[i].hash();
if(!p.count(ha)){
p.insert(ha);
ans++;
}
}
cout<<ans<<endl;
return 0;
}
KMP
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
/*----------------HUI----------------*/
inline void read(int &x){
x=0;int f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
char s1[1050500],s2[1050500];
int next[1050500],f[1050500];
int main(){
cin>>(s1+1);
cin>>(s2+1);
int m=strlen(s1+1);
int n=strlen(s2+1);
next[1]=0;
for(int i=2,j=0;i<=n;i++){
while(j>0&&s2[i]!=s2[j+1]) j=next[j];
if(s2[i]==s2[j+1]) j++;
next[i]=j;
}
for(int i=1,j=0;i<=m;i++){
while(j>0&&(j==m||s1[i]!=s2[j+1])) j=next[j];
if(s1[i]==s2[j+1]) j++;
f[i]=j;
if(f[i]==n){
cout<<i-n+1<<endl;
}
}
for(int i=1;i<=n;i++){
cout<<next[i]<<' ';
}
return 0;
}
tire
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
int idx=0;
int tir[500086];
char s[100];
int sum[505050];
bool vis[505050];
inline void insert(char *s){
int rt=0;
for(int i=0;s[i];i++){
int v=s[i]-'a';
if(!tir[rt]){
tir[rt]=++idx;
}
rt=tir[rt];
}
sum[rt]++;
vis[rt]=0;
}
inline int query(char *s){
int rt=0;
for(int i=0;s[i];i++){
int v=s[i]-'a';
if(!tirrt){
return 0;
}
rt=tirrt;
}
if(!sum[rt]){
return 0;
}
else if(vis[rt]==0){
vis[rt]=1;
return 1;
}
else{
return 2;
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
insert(s);
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>s;
int QAQ=query(s);
if(QAQ==0){
cout<<"WRONG"<<endl;
}
else if(QAQ==1){
cout<<"OK"<<endl;
}
else{
cout<<"REPEAT"<<endl;
}
}
return 0;
}
manacher
#include<map>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
/*----------------HUI----------------*/
char s[20505000],str[20505000];
int Len[20505000],len;
inline void getstr(){//处理要用的字符串
int k=0;
str[k++]='$';
for(int i=0;i<len;i++){
str[k++]='#';
str[k++]=s[i];
}
str[k++]='#';
len=k;
}
inline void manacher(){//manacher
getstr();
int mx=0,id;
for(int i=1;i<len;i++){
if(mx>i){
Len[i]=min(Len[2*id-i],mx-i);
}
else Len[i]=1;
while(str[i+Len[i]]==str[i-Len[i]]){
Len[i]++;
}
if(Len[i]+i>mx){
mx=Len[i]+i;
id=i;
}
}
}
int main(){
scanf("%s",&s);
len=strlen(s);
manacher();
int ans=1;
for(int i=1;i<len;i++) ans=max(ans,Len[i]);
printf("%d\n",ans-1);
return 0;
}
高精
struct node{
int s[10000];
int len;
node(){//名字和结构体名字一样(node)
memset(s,0,sizeof(s));
len=0;
}//结构体默认构造函数,新建时自动调用
void scan()//结构体成员函数,输入
{
char c[10000];
scanf("%s",c);
int o=strlen(c);
for(len=0;len<o;len++)
s[len]=c[o-len-1]-'0';//从左往右为从低位到高位
}
bool operator < (node p) const
{
if(len!=p.len) return len<p.len;
for(int i=len-1;i>=0;i--)
if(s[i]!=p.s[i]) return s[i]<p.s[i];
return 0;
}
bool operator == (node p) const
{
for(int i=max(len,p.len)-1;i>=0;i--)
if(s[i]!=p.s[i]) return 0;
return 1;
}
bool operator > (node p) const
{
if(len!=p.len) return len>p.len;
for(int i=len-1;i>=0;i--)
if(s[i]!=p.s[i]) return s[i]>p.s[i];
return 0;
}
node operator + (node a){//高精加高精
node c;
c.len=max(len,a.len);
for(int i=0;i<c.len;i++)
{
c.s[i]+=s[i]+a.s[i];
if(c.s[i]>9) c.s[i]-=10,c.s[i+1]++;
}
if(c.s[c.len]) c.len++;
return c;
}
node operator - (node a){//高精减高精
if(*this<a)
printf("-"),swap(*this,a);
for(int i=0;i<len;i++){
s[i]-=a.s[i];
while(s[i]<0) s[i]+=10,s[i+1]-=1;
}
if(!s[len-1]) len--;
while(!s[len-1])len--;
return *this;
}
node operator / (int a){//高精除低精
int x=0;//余数
node c;
c.len=len;
for(int i=len-1;i>=0;i--)
{
c.s[i]=(s[i]+x*10)/a;
x=s[i]%a;
}
if(!c.s[len-1]) c.len--;
return c;
}
node operator * (node a){//高精乘高精
node c;
for(int i=0;i<len;i++)
for(int j=0;j<a.len;j++){
c.s[i+j]+=s[i]*a.s[j];
if(c.s[i+j]>9) c.s[i+j+1]+=c.s[i+j]/10,c.s[i+j]%=10;
}
c.len=len+a.len;
if(!c.s[c.len-1]) c.len--;
return c;
}
node operator + (int a){//高精加低精
s[0]+=a;
int i=0;
while(s[i]>9) s[i]-=10,s[i+1]++,i++;
if(s[len]) len++;
return *this;//返回调用这个函数的自己
}
node operator - (int a){//高精减低精
s[0]-=a;
int i=0;
while(s[i]<0) s[i]+=10,s[i+1]--,i++;
if(!s[len-1]) len--;
return *this;//返回调用这个函数的自己
}
int operator % (int a){//高精度取模低精度
int re=0;
for(int i=0;i<len;i++)
re=(re*10+s[i])%a;
return re;
}
};