更不动了。。先鸽一鸽

oj有对应课件

后缀自动机

#include<bits/stdc++.h>
using namespace std;
struct jade
{
    int w[27];
	long long link,len,val;
}sam[2000010];
vector <int> t[2000010];
string s;
long long n,tot,last;
long long ans;
void build(long long x)
{
	tot++;
	long long np=tot,p=last;
	sam[np].len=sam[p].len+1;
	last=np;
	sam[np].val=1;
	while(p!=-1&&!sam[p].w[x])
	{
		sam[p].w[x]=np;
		p=sam[p].link;
	}
	if(p==-1)
	{
		sam[np].link=0;
		return ;
	}
	long long q=sam[p].w[x];
	if(sam[q].len==sam[p].len+1)
	{
		sam[np].link=q;
		return ;
	}
    tot++;
    long long nq=tot;
    memcpy(sam[nq].w,sam[q].w,sizeof(sam[q].w));
    sam[nq].len=sam[p].len+1;
    sam[nq].link=sam[q].link;
    sam[np].link=sam[q].link=nq;
    while(p!=-1&&sam[p].w[x]==q)
    {
    	sam[p].w[x]=nq;
    	p=sam[p].link;
	}
}
void dfs(long long x)
{
    for(auto y:t[x])
    {
    	dfs(y);
    	sam[x].val+=sam[y].val;
	}
	if(sam[x].val>1)
	{
		ans=max(ans,1ll*sam[x].val*sam[x].len);
	}
} 
int main()
{
	cin>>s;
	n=s.size();
	sam[0].link=-1;
	for(long long i=0;i<n;i++)
	{
        build(s[i]-'a'+1);
	} 
	for(long long i=1;i<=tot;i++)
	{
		t[sam[i].link].push_back(i);
	}
	dfs(0);
	cout<<ans;
	return 0;
}

树的重心 sdzx

#include<bits/stdc++.h>
using namespace std;
int n;
int h[100010],to[200010],nxt[200010],tot;
int ans=100010;
bool vis[100010];
void add(int x,int y)
{
	tot++;
	to[tot]=y;
	nxt[tot]=h[x];
	h[x]=tot; 
}
int dfs(int x)
{
    int res=0,sum=1;
	vis[x]=1;
	for(int i=h[x];i;i=nxt[i])
	{
	    int y=to[i];
		if(!vis[y])
		{
		    int ysum=dfs(y);
			res=max(res,ysum);
			sum+=ysum;
		}	
	}
	res=max(res,n-sum);
	ans=min(ans,res);
	return sum;	
} 
int main()
{
    cin>>n;
    for(int i=1;i<n;i++)
    {
    	int x,y;
    	cin>>x>>y;
    	add(x,y);
    	add(y,x);
	}
	dfs(1);
	cout<<ans;
    return 0;	
} 

点分治【国家集训队】聪聪可可

#include<bits/stdc++.h>
using namespace std;
int n;
int h[100010],to[200010],nxt[200010],v[200010],tot;
int maxx[100010]; 
bool vis[100010];
int size[100010];
int dis[100010],t[5],now[5];
int S;
int root;
int ans;
void add(int x,int y,int w)
{
	tot++;
	to[tot]=y;
	v[tot]=w;
	nxt[tot]=h[x];
	h[x]=tot; 
}
void getrt(int x,int fa)
{
    size[x]=1;
	maxx[x]=0;
	for(int i=h[x];i;i=nxt[i])
	{
	    int y=to[i];
		if(y==fa||vis[y])
		{
		    continue;
		}	
		getrt(y,x);
		size[x]+=size[y];
		maxx[x]=max(maxx[x],size[y]); 
	}	
	maxx[x]=max(maxx[x],S-size[x]);
	if(maxx[x]<maxx[root])
	{
		root=x;
	}
} 
void getnum(int x,int fa)
{
	now[dis[x]%3]++;
	for(int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if(vis[y]||fa==y)
		{
			continue;
		}
		dis[y]=dis[x]+v[i];
		getnum(y,x);
	}
}
void solve(int x)
{
	for(int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if(vis[y])
		{
		    continue;	
		} 
		memset(now,0,sizeof(now));
		dis[y]=v[i];
		getnum(y,x);
		ans+=t[0]*now[0]*2+t[1]*now[2]*2+t[2]*now[1]*2+now[0]*2;
		for(int j=0;j<3;j++)
		{
			t[j]+=now[j];
		}
	}
}
void Div(int x)
{
	vis[x]=1;
	solve(x);
	memset(t,0,sizeof(t));
	for(int i=h[x];i;i=nxt[i])
	{
		int y=to[i];
		if(vis[y])
		{
		    continue;
		} 
		S=size[y];
		root=0;
		maxx[0]=999999999;
		getrt(y,0); 
		Div(root);
	}
	return ;
}
int main()
{
    cin>>n;
    for(int i=1;i<n;i++)
    {
    	int x,y,w;
    	cin>>x>>y>>w;
    	add(x,y,w);
    	add(y,x,w);
	}
	maxx[root]=S=n;
	getrt(1,0);	
	Div(root);
	int a=ans+n;
	int b=n*n;
	int c=__gcd(a,b);
	cout<<a/c<<"/"<<b/c;
    return 0;	
}
 

cdq分治 三维偏序(陌上花开)

#include<bits/stdc++.h>
using namespace std;
struct jade
{
    int a,b,c,ans,cnt;
}s1[200010],s2[200010];
int n,m,k,maxx,top,f[200010];
int tr[200010];
bool cmp1(jade x,jade y)
{
    if(x.a==y.a)
    {
    	if(x.b==y.b)
    	{
    		return x.c<y.c;
		}
		else
		{
		    return x.b<y.b;	
		} 
	}
	else
	{
		return x.a<y.a;
	}
}
bool cmp2(jade x,jade y)
{
    if(x.b==y.b)
    {
    	return x.c<y.c;
	}
	else
	{
	    return x.b<y.b;	
	} 
}
int lowbit(int x)
{
	return x&(-x);
}
void add(int x,int y)
{
	for(int i=x;i<=maxx;i+=lowbit(i))
	{
	    tr[i]+=y;	
	} 
}
int find(int x)
{
    int res=0;
	for(int i=x;i>0;i-=lowbit(i))
	{
	    res+=tr[i];	
	}	

	return res;
} 
void cdq(int l,int r)
{
    if(l==r)
	{
	    return ;	
	}	 
	int mid=(l+r)>>1;
	cdq(l,mid);
	cdq(mid+1,r);
	sort(s2+l,s2+mid+1,cmp2);
	sort(s2+mid+1,s2+r+1,cmp2);
	int j=l;
	for(int i=mid+1;i<=r;i++)
	{
		while(s2[i].b>=s2[j].b&&j<=mid)
		{
			add(s2[j].c,s2[j].cnt);
			j++;
		}
		s2[i].ans+=find(s2[i].c);
	}
	for(int i=l;i<j;i++)
	{
		add(s2[i].c,-s2[i].cnt);	
	} 
}
int main()
{
	cin>>n>>k;
	maxx=k;
	for(int i=1;i<=n;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		s1[i].a=a;
		s1[i].b=b;
		s1[i].c=c;
	}
	sort(s1+1,s1+1+n,cmp1);
	for(int i=1;i<=n;i++)
	{
	    top++;
	    if(s1[i].a!=s1[i+1].a||s1[i].b!=s1[i+1].b||s1[i].c!=s1[i+1].c)
	    {
	    	m++;
	    	s2[m].a=s1[i].a;
	    	s2[m].b=s1[i].b;
	    	s2[m].c=s1[i].c;
	    	s2[m].cnt=top;
	    	top=0;
		}
	}
	cdq(1,m);
	for(int i=1;i<=m;i++)
	{
	    f[s2[i].ans+s2[i].cnt-1]+=s2[i].cnt;	
	} 
	for(int i=0;i<n;i++)
	{
		cout<<f[i]<<endl;
	}
}

网络流

最大流[SCOI2007]蜥蜴

#include<bits/stdc++.h>
using namespace std;
int n,m,d,T;
int ans,sum;
int tot=1;
int cur[100010];
int h[100010],to[200010],nxt[200010],v[200010];
int dis[100010];
int s,t,k;
struct jade
{
    int x,y,v;
}e[20001];
int cnt,rnt;
string ss;
int s1[55][55],s2[55][55];
void add(int x,int y,int w)
{
    tot++;
    to[tot]=y;
    nxt[tot]=h[x];
    v[tot]=w;
    h[x]=tot;
}
bool bfs()
{
    memset(dis,0,sizeof(dis));
    queue<int>q;
    q.push(s);
    dis[s]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=h[x];i;i=nxt[i])
        {
            int y=to[i];
            if(!dis[y]&&v[i])
            {
                dis[y]=dis[x]+1;
                q.push(y);
            }
        }
    }
    if(dis[t]==0)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
int dfs(int x,int rest)
{
    if(x==t)
    {
        return rest;
    }
    int flow=0;
    for(int &i=cur[x];i&&rest;i=nxt[i])
    {
        int y=to[i];
        if(dis[x]+1==dis[y]&&v[i])
        {
            int k=dfs(y,min(rest,v[i]));
            flow+=k;
            rest-=k;
            v[i]-=k;
            v[i^1]+=k;
            if(rest<=0)
            {
                return flow;
            }
        }
    }
    if(!flow)
    {
        dis[x]=0;
    }
    return flow;
}
int dinic()
{
    int ans=0;
    while(bfs())
    {
        memcpy(cur,h,sizeof(cur));
        ans+=dfs(s,1e8);
    }
    return ans;
}
int main()
{
    cin>>n>>m>>d;
    s=0,t=n*m*2+1;
    for(int i=1;i<=n;i++)
    {
        cin>>ss;
        for(int j=1;j<=m;j++)
        {
            int x=ss[j-1]-'0';
            if(x!=0)
            {
                add((i-1)*m+j,(i-1)*m+j+n*m,x);
                add((i-1)*m+j+n*m,(i-1)*m+j,0);
            }
        }
    }
    for(int i=1;i<=cnt;i++)
    {
        add(i+cnt,i,0);
        add(i,i+cnt,e[i].v);
    }
    for(int i=1;i<=n;i++)
    {
        cin>>ss;
        for(int j=1;j<=m;j++)
        {
            if(ss[j-1]=='L')
            {
                rnt++;
                add(s,(i-1)*m+j,1);
                add((i-1)*m+j,s,0);
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            for(int x=1;x<=n;x++)
            {
                for(int y=1;y<=m;y++)
                {
                    if((i-x)*(i-x)+(j-y)*(j-y)<=d*d)
                    {
                        add((i-1)*m+j+n*m,(x-1)*m+y,1e8);
                        add((x-1)*m+y,(i-1)*m+j+n*m,0);
                    }
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i+d>n||i-d<1||j+d>m||j-d<1)
            {
                add((i-1)*m+j+n*m,t,1e8);
                add(t,(i-1)*m+j+n*m,0);
            }
        }
    }
    cout<<rnt-dinic();
    return 0;
}

独角兽/杜教筛

#include<bits/stdc++.h>
using namespace std;
unordered_map<long long,long long> dmo,dphip;
long long p[2000001],mu[2000001],mo[2000001],phi[2000001],phip[2000001],tot,fj;
bool isp[2000001];
void prime(long long n)
{
    mu[1]=1,phi[1]=1,isp[1]=1;
	for(long long i=2;i<=n;i++)
	{
	    if(isp[i]==0)
	    {
	    	tot++;
	    	p[tot]=i;
	    	mu[i]=-1;
	    	phi[i]=i-1;
		}
		for(long long j=1;j<=tot&&i*p[j]<=n;j++)
		{
			isp[i*p[j]]=1;
			if(i%p[j]==0)
			{
				phi[i*p[j]]=phi[i]*p[j];
				break;
			}
			mu[i*p[j]]=-mu[i];
			phi[i*p[j]]=phi[i]*(p[j]-1);
		}
	} 
}
long long summo(long long n)
{
	if(n<=fj)
	{
		return mo[n];
	}
	if(dmo[n]!=0)
	{
		return dmo[n];
	}
	long long s=1;
	for(long long l=2,r;l<=n;l=r+1)
	{
	    r=n/(n/l);
	    s-=(r-l+1)*summo(n/l);
	} 
	dmo[n]=s;
	return s;
}
long long sumphi(long long n)
{
	if(n<=fj)
	{
		return phip[n];
	}
	if(dphip[n]!=0)
	{
		return dphip[n];
	}
	long long s=n*(n+1)/2;
	for(long long l=2,r;l<=n;l=r+1)
	{
		r=n/(n/l);
		s-=(r-l+1)*sumphi(n/l);
	}
	dphip[n]=s;
	return s;
}
int main()
{
	prime(2000000);
	for(long long i=1;i<=2000000;i++)
	{
		mo[i]=mo[i-1]+mu[i];
		phip[i]=phip[i-1]+phi[i];
	}
	long long T;
	cin>>T;
	while(T--)
	{
		long long n;
		cin>>n;
		fj=cbrt(n)*cbrt(n);
		cout<<sumphi(n)<<" "<<summo(n)<<endl;		 
	}
	return 0;
}

回文自动机板子

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int n,tot=1;
struct jade
{
	int len,fa,dep,c[26];
}t[N];
string s;
int get_fail(int x,int i)
{
	while(i-t[x].len-1<=0||s[i-1-t[x].len-1]!=s[i-1])
	{
		x=t[x].fa;
	}
	return x;
}
int main()
{
    cin>>s;
    n=s.size();
    t[0].fa=1;
    t[1].len=-1;
    int now=0,last=0;
    for(int i=1;i<=n;i++)
    {
    	s[i-1]=(s[i-1]-'a'+last)%26+'a';
    	int pos=get_fail(now,i);
    	int num=s[i-1]-'a';
    	if(!t[pos].c[num])
		{
		    tot++;
		    t[tot].fa=t[get_fail(t[pos].fa,i)].c[num];
		    t[pos].c[num]=tot;
		    t[tot].len=t[pos].len+2;
		    t[tot].dep=t[t[tot].fa].dep+1;
		} 
		now=t[pos].c[num];
		cout<<t[now].dep<<" ";
		last=t[now].dep;
    }
	return 0;
}
posted @ 2025-07-28 16:23  BIxuan—玉寻  阅读(14)  评论(0)    收藏  举报