板子

后缀自动机

#include<bits/stdc++.h>
#define re register
#define ll long long
#define inc(i,j,k) for(re int i=j;i<=k;i++)
using namespace std;
const int MAXN=1000005;
struct state{
	int len,link,mp[30];
}st[MAXN<<1];
struct edge{
	int to,nxt;
}e[MAXN<<1];
queue<int> q;
ll ans;
char s[MAXN];
int sz,last,cnt,head[MAXN<<1],num[MAXN<<1];
void add(int a,int b){
	e[++cnt].to=b;
	e[cnt].nxt=head[a];
	head[a]=cnt;
}
void sa_init(){
	st[sz].len=0;
	st[sz].link=-1;
	last=sz;
}
void sa_extend(int c){
	int cur=++sz;
	num[sz]=1;
	st[cur].len=st[last].len+1;
	int p=last;
	while(p!=-1&&!st[p].mp[c]){
		st[p].mp[c]=cur;
		p=st[p].link;
	}
	if(p==-1) st[cur].link=0;
	else{
		int q=st[p].mp[c];
		if(st[q].len==st[p].len+1)  st[cur].link=q;
		else{
			int clone=++sz;
			st[clone].len=st[p].len+1;
			inc(i,0,25) st[clone].mp[i]=st[q].mp[i];
			st[clone].link=st[q].link;
			while(p!=-1&&st[p].mp[c]==q){
				st[p].mp[c]=clone;
				p=st[p].link;
			}
			st[q].link=st[cur].link=clone;
		} 
	}
	last=cur;
}
void dfs(int u){
	for(re int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		dfs(v);
		num[u]+=num[v];
	}
	if(num[u]!=1) ans=max(ans,(ll)num[u]*st[u].len);
}
int main(){
	scanf("%s",s+1);
	int len=strlen(s+1);
	sa_init();
	inc(i,1,len) sa_extend(s[i]-'a');
	inc(i,1,sz) add(st[i].link,i);
	dfs(0);
	printf("%lld",ans);
}

后缀数组

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
#define dec(i,j,k) for(re int i=j;i>=k;i--)
using namespace std;
const int MAXN=1000005;
char s[MAXN];
int sa[MAXN],rank[MAXN],tp[MAXN],a[MAXN],n,m,cnt[MAXN];
void sa_sort(){
	inc(i,0,m) cnt[i]=0;
	inc(i,1,n) cnt[rank[tp[i]]]++;
	inc(i,1,m) cnt[i]+=cnt[i-1];
	dec(i,n,1) sa[cnt[rank[tp[i]]]--]=tp[i];
}
void get_sa(){
	inc(i,1,n) rank[i]=a[i],tp[i]=i;
	m=127,sa_sort();
	for(re int k=1,p=0;p<n;k<<=1,m=p){
		p=0;
		inc(i,n-k+1,n) tp[++p]=i;
		inc(i,1,n) if(sa[i]>k) tp[++p]=sa[i]-k;
		sa_sort(),swap(rank,tp),rank[sa[1]]=p=1;
		inc(i,2,n) rank[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+k]==tp[sa[i-1]+k])?p:++p;
	}
}
int main(){
	scanf("%s",s+1);
	n=strlen(s+1);
	inc(i,1,n) a[i]=s[i];
	get_sa();
	inc(i,1,n) printf("%d ",sa[i]);
}

回文自动机

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
using namespace std;
const int N=5e5+5;
char s[N];
int ch[N][26],len[N],fa[N],num[N],tot,ans,last;
void init(){tot=1,fa[0]=fa[1]=1,len[1]=-1;}
void extend(int c,int i){
	int p=last;
	while(s[i-len[p]-1]!=s[i]) p=fa[p];
	if(!ch[p][c]){
		int k=fa[p];
		while(s[i-len[k]-1]!=s[i]) k=fa[k];
		fa[++tot]=ch[k][c];
		ch[p][c]=tot;
		len[tot]=len[p]+2,num[tot]=num[fa[tot]]+1;
	}
	printf("%d ",ans=num[ch[p][c]]);
	last=ch[p][c];
}
int main(){
	scanf("%s",s+1);
	int n=strlen(s+1);init();
	inc(i,1,n) s[i]=(s[i]-97+ans)%26+97,extend(s[i]-'a',i);
}

AC自动机

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
using namespace std;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
	return f*x;
}
const int MAXN=200005;
queue<int> qq;
int n,ch[MAXN][26],nxt[MAXN],tot,cnt,val[MAXN],ru[MAXN],head[MAXN],num,ans[MAXN],pos[MAXN];
char s[MAXN*10];
struct edge{
	int to,nxt;
}e[MAXN];
void add(int a,int b){
	e[++num].to=b;
	e[num].nxt=head[a];
	head[a]=num;
}
void insert(char *s){
	int len=strlen(s+1);
	int u=0;
	inc(i,1,len){
		int c=s[i]-'a';
		if(!ch[u][c]) ch[u][c]=++tot;
		u=ch[u][c];
	}
	pos[++cnt]=u;
}
void build(){
	queue<int> q;
	inc(i,0,25) if(ch[0][i]) nxt[ch[0][i]]=0,q.push(ch[0][i]);
	while(q.size()){
		int u=q.front();
		q.pop();
		inc(i,0,25){
			if(ch[u][i]) nxt[ch[u][i]]=ch[nxt[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[nxt[u]][i];
		} 
	}
}
void find(char *s){
	int len=strlen(s+1);
	int u=0;
	inc(i,1,len){
		int c=s[i]-'a';
		u=ch[u][c],val[u]++;
	}
}
int main(){
	n=read();
	inc(i,1,n){
		scanf("%s",s+1);
		insert(s);
	}
	build();
	scanf("%s",s+1);
	find(s);
	inc(i,1,tot) add(i,nxt[i]),ru[nxt[i]]++;
	inc(i,1,tot) if(!ru[i]) qq.push(i);
	while(qq.size()){
		int u=qq.front();
		qq.pop();
		for(re int i=head[u];i;i=e[i].nxt){
			int v=e[i].to;
			val[v]+=val[u];
			ru[v]--;
			if(!ru[v]) qq.push(v);
		}
	}
	inc(i,1,n) printf("%d\n",val[pos[i]]);
}

Z函数

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
#define ll long long
using namespace std;
const int N=2e7+5;
inline int read(){
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
char s[N],t[N];
int n,m,z[N],p[N];
ll ans;
void getz(){
	z[1]=m;int l=0,r=0;
	inc(i,2,m){
		if(i<=r) z[i]=min(z[i-l+1],r-i+1);
		while(i+z[i]<=m&&t[i+z[i]]==t[z[i]+1]) z[i]++;
		if(i+z[i]-1>r) l=i,r=i+z[i]-1;
	}
}
void exkmp(){
	int l=0,r=0;
	inc(i,1,n){
		if(i<=r) p[i]=min(z[i-l+1],r-i+1);
		while(i+p[i]<=n&&s[i+p[i]]==t[p[i]+1]) p[i]++;
		if(i+p[i]-1>r) l=i,r=i+p[i]-1; 
	}
}
int main(){
	scanf("%s",s+1);
	n=strlen(s+1);
	scanf("%s",t+1);
	m=strlen(t+1);
	getz(),exkmp();
	ans=0;
	inc(i,1,m) ans^=1LL*i*(z[i]+1);
	printf("%lld\n",ans);
	ans=0;
	inc(i,1,n) ans^=1LL*i*(p[i]+1);
	printf("%lld\n",ans);
}

kmp

#include<bits/stdc++.h>
#define maxn 1000010
using namespace std;
char a[maxn],b[maxn];
int nxt[maxn];
int main(){
	scanf("%s",a+1);
	scanf("%s",b+1);
	int j=0;
	int la=strlen(a+1),lb=strlen(b+1);
	for(int i=2;i<=lb;++i){
		while(j && b[i]!=b[j+1]) j=nxt[j];
		if(b[i]==b[j+1]) j++;
		nxt[i]=j;
	}
	j=0;
	for(int i=1;i<=la;++i){
		while(j && a[i]!=b[j+1]) j=nxt[j];
		if(a[i]==b[j+1]) j++;
		if(j==lb){
			printf("%d\n",i-lb+1);
			j=nxt[j];
		}
	}
	for(int i=1;i<=lb;++i) printf("%d ",nxt[i]);
	return 0;
}

线段树套平衡树

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
using namespace std;
const int MAXN=4000005;
const int inf=2147483647;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
	return f*x;
}
struct Splay{
	int root[MAXN],cnt;
	struct tree{
		int ch[2],pre,val,size,cnt;
		#define fa(x) t[x].pre
		#define lc(x) t[x].ch[0]
		#define rc(x) t[x].ch[1]
	}t[MAXN];
	bool check(int x){return rc(fa(x))==x;}
	void connect(int x,int fa,int type){fa(x)=fa,t[fa].ch[type]=x;}
	void pushup(int x){t[x].size=t[lc(x)].size+t[rc(x)].size+t[x].cnt;}
	void rotate(int x){
		int y=fa(x),z=fa(y),k=check(x),w=t[x].ch[k^1];
		fa(x)=z;
		if(z) connect(x,z,check(y)); 
		connect(w,y,k);
		connect(y,x,k^1);
		pushup(y),pushup(x);
	}
	void splay(int x,int goal,int k){
		while(fa(x)!=goal){
			int y=fa(x);
			if(fa(y)!=goal){
				if(check(x)==check(y)) rotate(y);
				else rotate(x);
			}
			rotate(x);
		}
		if(!goal) root[k]=x;
	}
	void insert(int val,int k){
		int tmp=root[k],p=0;
		while(tmp&&t[tmp].val!=val) p=tmp,tmp=t[tmp].ch[val>t[tmp].val];
		if(tmp) t[tmp].cnt++;
		else{
			tmp=++cnt;
			fa(tmp)=p;
			if(p) connect(tmp,p,val>t[p].val); 
			t[tmp].val=val;
			t[tmp].size=t[tmp].cnt=1;
		}
		splay(tmp,0,k);	
	}
	void find(int val,int k){
		int tmp=root[k];
		while(t[tmp].ch[val>t[tmp].val]&&val!=t[tmp].val) tmp=t[tmp].ch[val>t[tmp].val];
		splay(tmp,0,k);
	}
	int pre(int val,int k){
		find(val,k);
		if(t[root[k]].val<val) return root[k];
		int tmp=lc(root[k]); 
		while(rc(tmp)) tmp=rc(tmp);
		return tmp;
	}
	int nxt(int val,int k){
		find(val,k);
		if(t[root[k]].val>val) return root[k];
		int tmp=rc(root[k]);
		while(lc(tmp)) tmp=lc(tmp);
		return tmp;
	}
    void remove(int val,int k){
    	int first=pre(val,k),last=nxt(val,k);
    	splay(first,0,k),splay(last,first,k);
    	int tmp=lc(last);
		if(t[tmp].cnt>1){
    		t[tmp].cnt--;
    		splay(tmp,0,k);
		}
		else lc(last)=0;
	}
	int rank(int x,int val){
		if(!x) return 0;
		if(t[x].val<val) return t[lc(x)].size+t[x].cnt+rank(rc(x),val);
		if(t[x].val==val) return t[lc(x)].size;
		return rank(lc(x),val);
	}
}bt;
int n,m,a[MAXN];
struct tree{
	#define ls o<<1
	#define rs o<<1|1 
    void build(int o,int l,int r){
    	bt.insert(inf,o),bt.insert(-inf,o);
		inc(i,l,r) bt.insert(a[i],o);
    	if(l==r) return;
    	int mid=l+r>>1;
    	build(ls,l,mid),build(rs,mid+1,r);
	}
	void change(int o,int l,int r,int pos,int val){
		bt.remove(a[pos],o),bt.insert(val,o);
		if(l==r){a[pos]=val;return;}
		int mid=l+r>>1;
		if(pos<=mid) change(ls,l,mid,pos,val);
		else change(rs,mid+1,r,pos,val);
	}
	int query_pre(int o,int l,int r,int x,int y,int val){
		if(x<=l&&r<=y) return bt.t[bt.pre(val,o)].val;
		int mid=l+r>>1,res=-inf;
		if(x<=mid) res=max(res,query_pre(ls,l,mid,x,y,val));
		if(mid<y) res=max(res,query_pre(rs,mid+1,r,x,y,val));
		return res;
	}
	int query_nxt(int o,int l,int r,int x,int y,int val){
		if(x<=l&&r<=y) return bt.t[bt.nxt(val,o)].val;
		int mid=l+r>>1,res=inf;
		if(x<=mid) res=min(res,query_nxt(ls,l,mid,x,y,val));
		if(mid<y) res=min(res,query_nxt(rs,mid+1,r,x,y,val));
		return res;
	}
	int query_rank(int o,int l,int r,int x,int y,int val){
		if(x<=l&&r<=y) return bt.rank(bt.root[o],val)-1;	
		int mid=l+r>>1,res=0;
		if(x<=mid) res+=query_rank(ls,l,mid,x,y,val);
		if(mid<y) res+=query_rank(rs,mid+1,r,x,y,val);
		return res;
	}
	int query_kth(int x,int y,int k){
		int l=0,r=100000005;
		while(l<r){
			int mid=l+r>>1;
			int tmp=query_rank(1,1,n,x,y,mid);
			if(tmp<k) l=mid+1; 
			else r=mid;
		}
		return l-1;
	}
}tt;
void init(){
	n=read(),m=read();
	inc(i,1,n) a[i]=read();	
	tt.build(1,1,n);
}
void work(){
	int opt,x,y,k,pos;
	inc(i,1,m){
		opt=read();
		if(opt==1){
			x=read(),y=read(),k=read();
			printf("%d\n",tt.query_rank(1,1,n,x,y,k)+1);
		}
		if(opt==2){
			x=read(),y=read(),k=read();
			printf("%d\n",tt.query_kth(x,y,k));
		}
		if(opt==3){
			pos=read(),k=read();
			tt.change(1,1,n,pos,k);
		}
		if(opt==4){
			x=read(),y=read(),k=read();
			printf("%d\n",tt.query_pre(1,1,n,x,y,k));
		} 
		if(opt==5){
			x=read(),y=read(),k=read();
			printf("%d\n",tt.query_nxt(1,1,n,x,y,k)); 
		}
	}
}
int main(){
    init();
    work();
} 

可持久化平衡树

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
#define inf 2147483647
using namespace std;
const int MAXN=500005;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
	return f*x;
}
int n,root[MAXN],opt,x;
struct fhq_treap{
	struct node{
		int ch[2],val,size,key;
		#define lc(x) t[x].ch[0]
		#define rc(x) t[x].ch[1]
	}t[MAXN*50];
	int cnt;
	void pushup(int x){t[x].size=t[lc(x)].size+t[rc(x)].size+1;}
	void newnode(int &x,int val){
		t[x=++cnt].val=val,t[cnt].key=rand(),t[cnt].size=1;
	}
	int merge(int x,int y){
		if(!x||!y) return x+y;
		if(t[x].key>t[y].key){
			int tmp=++cnt;
			t[tmp]=t[x];
			rc(tmp)=merge(rc(tmp),y);
			pushup(tmp);return tmp; 
		} 
		else{
			int tmp=++cnt;
			t[tmp]=t[y];
			lc(tmp)=merge(x,lc(tmp)); 
			pushup(tmp);return tmp;
		}
	}
	void split(int tmp,int val,int &x,int &y){
		if(!tmp) x=y=0;
		else{
			if(t[tmp].val<=val){
				x=++cnt,t[x]=t[tmp];
				split(rc(x),val,rc(x),y);
				pushup(x);
			}
			else{
				y=++cnt,t[y]=t[tmp];
				split(lc(y),val,x,lc(y));
				pushup(y);
			}
		}
	}
	void remove(int &tmp,int val){
		int x=0,y=0,z=0;
		split(tmp,val,x,z);
		split(x,val-1,x,y);
		y=merge(lc(y),rc(y));
		tmp=merge(merge(x,y),z);
	}
	void insert(int &tmp,int val){
		int x=0,y=0,z=0;
		split(tmp,val,x,y);
		newnode(z,val);
		tmp=merge(merge(x,z),y);
	}
	int getval(int x,int k){
		if(t[lc(x)].size+1==k) return t[x].val;
		else if(k<=t[lc(x)].size) return getval(lc(x),k);
		else return getval(rc(x),k-t[lc(x)].size-1);
	}
	int getrank(int &tmp,int val){
		int x,y;
		split(tmp,val-1,x,y);
		int res=t[x].size+1;
		tmp=merge(x,y);
		return res;
	}
	int getpre(int &tmp,int val){
		int x,y,res;
		split(tmp,val-1,x,y);
		if(!x) return -inf;
		int k=t[x].size;
		res=getval(x,k);
		tmp=merge(x,y);
		return res;
	}
	int getnxt(int &tmp,int val){
		int x,y,res;
		split(tmp,val,x,y);
		if(!y) return inf;
		res=getval(y,1);
		tmp=merge(x,y);
		return res;
	}
}tp;
int main(){
	n=read();
	inc(i,1,n){
		root[i]=root[read()];
		opt=read(),x=read();
		if(opt==1) tp.insert(root[i],x);
		if(opt==2) tp.remove(root[i],x);
		if(opt==3) printf("%d\n",tp.getrank(root[i],x));
		if(opt==4) printf("%d\n",tp.getval(root[i],x));
		if(opt==5) printf("%d\n",tp.getpre(root[i],x));
		if(opt==6) printf("%d\n",tp.getnxt(root[i],x));
	}
}
#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
#define fa(x) t[x].fa
#define lc(x) t[x].ch[0]
#define rc(x) t[x].ch[1] 
using namespace std;
const int MAXN=300005;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
	return f*x;
}
struct node{
	int ch[2],fa,val,flag;
}t[MAXN];
int n,m,ins,x,y,a[MAXN],st[MAXN],top,cnt;
bool check(int x){
	return t[fa(x)].ch[1]==x;
}
bool nroot(int x){
	return lc(fa(x))==x||rc(fa(x))==x;
}
void pushup(int x){
	t[x].val=t[lc(x)].val^t[rc(x)].val^a[x];
}
void connect(int x,int fa,int type){
	fa(x)=fa;
	t[fa].ch[type]=x;
}
void pushdown(int x){
	if(t[x].flag){
		t[lc(x)].flag^=1;
		t[rc(x)].flag^=1;
		swap(lc(x),rc(x));
		t[x].flag=0;
	}
}
void rotate(int x){
	int y=fa(x),z=fa(y),k=check(x),w=t[x].ch[k^1];
	t[x].fa=z;
	if(nroot(y)) connect(x,z,check(y));
	connect(w,y,k);
	connect(y,x,k^1);
	pushup(y),pushup(x);
}
void splay(int x){
	int k=x,top=0;
	while(nroot(k)) st[++top]=k,k=fa(k);
	st[++top]=k;
	while(top) pushdown(st[top--]);
	while(nroot(x)){
	    int y=fa(x);
		if(nroot(y)){
			if(check(x)==check(y)) rotate(y);
			else rotate(x);
		}
		rotate(x);
	}
}
void access(int x){
	int y=0;
	while(x){
		splay(x);
		rc(x)=y;
		pushup(x);
		y=x;
		x=fa(x);
	}
}
void makeroot(int x){
	access(x);
	splay(x);
	t[x].flag^=1;
	pushdown(x);
}
int findroot(int x){
	access(x);
	splay(x);
	while(lc(x)) pushdown(x),x=lc(x);
	return x;
}
void split(int x,int y){
	makeroot(x);
	access(y);
	splay(y);
}
void link(int x,int y){
	makeroot(x);
	if(findroot(y)!=x) fa(x)=y;
}
void cut(int x,int y){
	makeroot(x);
	if(findroot(y)==x&&fa(x)==y&&lc(y)==x&&!rc(x)){
		fa(x)=t[y].ch[0]=0;
		pushup(y);
	}
}
int main(){
	n=read(),m=read();
	inc(i,1,n) a[i]=read();
	inc(i,1,m){
		ins=read(),x=read(),y=read();
		if(ins==0) split(x,y),printf("%d\n",t[y].val);
		if(ins==1) link(x,y);
		if(ins==2) cut(x,y);
		if(ins==3) splay(x),a[x]=y;
	}
	return 0;
}

动态dp

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
#define dec(i,j,k) for(re int i=j;i>=k;i--)
#define inf 2147483647
#define int long long
using namespace std;
const int MAXN=100005;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
	return f*x;
}
int n,m,a,b,cnt,dep[MAXN],size[MAXN],f[MAXN][2],g[MAXN][2],seg[MAXN],rev[MAXN],fa[MAXN],top[MAXN],son[MAXN],val[MAXN],bot[MAXN],u,w,head[MAXN];
struct edge{
	int to,nxt;
}e[MAXN<<1];
void add(int a,int b){
	e[++cnt].to=b;
	e[cnt].nxt=head[a];
	head[a]=cnt;
}
void dfs1(int u,int ff){
	dep[u]=dep[ff]+1,fa[u]=ff,size[u]=1;
	for(re int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==ff) continue;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>size[son[u]]) son[u]=v;
	}
}
void dfs2(int u,int ff){
	g[u][1]=val[u];
	if(son[u]){
		top[son[u]]=top[u];
		seg[son[u]]=++seg[0];
		rev[seg[0]]=son[u];
		dfs2(son[u],u);
	}
	for(re int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(!top[v]){
			top[v]=v;
			seg[v]=++seg[0];
			rev[seg[0]]=v;
			dfs2(v,u);
			g[u][0]+=max(f[v][0],f[v][1]);
			g[u][1]+=f[v][0];
		}
	}
	if(son[u]) bot[u]=bot[son[u]];
	else bot[u]=u;
	f[u][0]=g[u][0]+max(f[son[u]][0],f[son[u]][1]);
	f[u][1]=g[u][1]+f[son[u]][0];
}
struct martix{
	int m[2][2];
}tmp[MAXN];
martix operator*(martix a,martix b){
		martix tmp;
		tmp.m[0][0]=max(a.m[0][0]+b.m[0][0],a.m[0][1]+b.m[1][0]);
		tmp.m[1][0]=max(a.m[1][0]+b.m[0][0],a.m[1][1]+b.m[1][0]);
		tmp.m[0][1]=max(a.m[0][0]+b.m[0][1],a.m[0][1]+b.m[1][1]);
		tmp.m[1][1]=max(a.m[1][0]+b.m[0][1],a.m[1][1]+b.m[1][1]);
		return tmp;
}
struct tree{
	int l,r;
	martix data;
}t[MAXN<<2];
void pushup(int o){
	t[o].data=t[o<<1].data*t[o<<1|1].data;
}
void build(int o,int l,int r){
	t[o].l=l,t[o].r=r;
	if(l==r){
		tmp[l]=t[o].data=(martix){g[rev[l]][0],g[rev[l]][0],g[rev[l]][1],-inf};
		return;
	}
	int mid=l+r>>1;
	build(o<<1,l,mid),build(o<<1|1,mid+1,r);
	pushup(o);
}
void change(int o,int p){
	if(t[o].l==p&&t[o].r==p){
		t[o].data=tmp[p];	
		return;
	}
	int mid=t[o].l+t[o].r>>1;
	if(p<=mid) change(o<<1,p);
	else change(o<<1|1,p);
	pushup(o);
}
martix query(int o,int x,int y){
	if(x<=t[o].l&&t[o].r<=y){
		return t[o].data;
	}
	int mid=t[o].l+t[o].r>>1;
	if(y<=mid) return query(o<<1,x,y);
	if(x>mid) return query(o<<1|1,x,y);
	return query(o<<1,x,y)*query(o<<1|1,x,y);
}
void modify(int u,int w){
	tmp[seg[u]].m[1][0]+=(w-val[u]),val[u]=w;
	while(u){
		martix a=query(1,seg[top[u]],seg[bot[u]]);
		change(1,seg[u]);
		martix b=query(1,seg[top[u]],seg[bot[u]]);
		u=fa[top[u]];
		if(!u)break;
		int x=seg[u];
		int g0=a.m[0][0],g1=a.m[1][0],f0=b.m[0][0],f1=b.m[1][0];
		tmp[x].m[0][0]=tmp[x].m[0][1]=tmp[x].m[0][0]+max(f1,f0)-max(g1,g0);
		tmp[x].m[1][0]=tmp[x].m[1][0]+f0-g0;
	}
}
signed main(){
	n=read(),m=read();
	inc(i,1,n) val[i]=read();
	inc(i,2,n){
		a=read(),b=read();
		add(a,b),add(b,a);
	} 	
	dfs1(1,0);
	top[1]=1,seg[1]=++seg[0],rev[seg[0]]=1;
	dfs2(1,0);
	build(1,1,n);
	inc(i,1,m){
		u=read(),w=read();
		modify(u,w);
		martix ans=query(1,seg[1],seg[bot[1]]);
		printf("%lld\n",max(ans.m[0][0],ans.m[1][0]));
	}
}

可并堆

#include<bits/stdc++.h>
#define re register
#define inc(i,j,k) for(re int i=j;i<=k;i++)
using namespace std;
const int MAXN=100005;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=x*10+ch-'0',ch=getchar();}
	return f*x;
}
int n,m,val[MAXN],ch[MAXN][2],dis[MAXN],fa[MAXN],ins,x,y;
int getfa(int x){
	return fa[x]==x?x:fa[x]=getfa(fa[x]);
}
int merge(int x,int y){
	if(x==0||y==0) return x+y;
	if(val[x]>val[y]||(val[x]==val[y]&&x>y)) swap(x,y);
	ch[x][1]=merge(ch[x][1],y);
	if(dis[ch[x][0]]<dis[ch[x][1]]) swap(ch[x][0],ch[x][1]);
	dis[x]=dis[ch[x][1]]+1;
	fa[ch[x][0]]=fa[ch[x][1]]=x;
	return x;
}
int pop(int x){
	int tmp=val[x];val[x]=-1;
	fa[ch[x][0]]=ch[x][0];
	fa[ch[x][1]]=ch[x][1];
	fa[x]=merge(ch[x][0],ch[x][1]);
	return tmp;
}
int main(){
	n=read(),m=read();
	inc(i,1,n) val[i]=read(),fa[i]=i;
	inc(i,1,m){
		ins=read();
		if(ins==1){
			x=read(),y=read();
			if(val[x]==-1||val[y]==-1) continue;
			int fx=getfa(x),fy=getfa(y);
			if(fx==fy) continue;
			merge(fx,fy);
		}
		else{
			x=read();
			if(val[x]==-1){
				puts("-1");
				continue;
			}
			int fx=getfa(x);
			printf("%d\n",pop(fx));
		}
	}
}

min_25筛

#include<bits/stdc++.h>
#define re register
#define ll long long
#define inc(i,j,k) for(re ll i=j;i<=k;i++)
using namespace std; 
const int mod=1e9+7;
const int inv2=5e8+4;
const int inv6=166666668;
const int N=1e6+5;
inline ll read(){
	ll x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
int len,tot,id1[N],id2[N],cnt;
ll prime[N],sp1[N],sp2[N];
ll n,g1[N],g2[N],w[N];
bool check[N];
void init(int n){
	inc(i,2,n){
		if(!check[i]){
			prime[++tot]=i;
			sp1[tot]=(sp1[tot-1]+i)%mod;
			sp2[tot]=(sp2[tot-1]+1LL*i*i)%mod;
		}
		inc(j,1,tot){
			if(i*prime[j]>n) break;
			check[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
ll s(ll i,int j){
	if(prime[j]>=i) return 0;
	int u=i<=len?id1[i]:id2[n/i];
	ll ans=(g2[u]-g1[u]-sp2[j]+sp1[j]+2*mod)%mod;
	inc(p,j+1,tot){
		if(prime[p]*prime[p]>i) break;
		ll pe=prime[p];
		for(re int e=1;pe<=i;e++,pe=pe*prime[p]){
			ll cur=pe%mod;
			(ans+=cur*(cur-1)%mod*(s(i/pe,p)+(e!=1))%mod)%=mod;
		}
	}
	return ans;
}
int main(){
	n=read();len=sqrt(n);init(len);
	for(re ll l=1,r;l<=n;l=r+1){
		r=n/(n/l),w[++cnt]=n/l;
		ll cur=w[cnt]%mod;
		g1[cnt]=cur*(cur+1)%mod*inv2%mod;
		g2[cnt]=cur*(cur+1)%mod*(2*cur+1)%mod*inv6%mod;
		(g1[cnt]+=mod-1)%=mod,(g2[cnt]+=mod-1)%=mod;
		if(n/l<=len) id1[n/l]=cnt;
		else id2[n/(n/l)]=cnt;
	}
	inc(i,1,tot){
		inc(j,1,cnt){
			if(prime[i]*prime[i]>w[j]) break;
			int u=w[j]/prime[i]<=len?id1[w[j]/prime[i]]:id2[n/(w[j]/prime[i])];
			(g1[j]+=mod-prime[i]*(g1[u]-sp1[i-1]+mod)%mod)%=mod;
			(g2[j]+=mod-prime[i]*prime[i]%mod*(g2[u]-sp2[i-1]+mod)%mod)%=mod;
		}
	}
	printf("%lld",(s(n,0)+1)%mod);
	return 0;
}
posted @ 2021-11-10 16:05  forxen  阅读(43)  评论(0)    收藏  举报