板子合集


my 缺省源

点击查看代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define pb push_back
#define mp std::make_pair
#define ulf Useful_little_function
#define abs ccf
#define INF (0x3f3f3f3f)
#define INT_INF (2147483647)
#define LLINF (0x3f3f3f3f3f3f3f3fll)
#define LL_INF (9223372036854775807)
#define memset __builtin_memset
#define popcount __builtin_popcount
std::mt19937 rnd(std::chrono::system_clock::now().time_since_epoch().count());
typedef long long ll;
typedef std::pair pii;
typedef unsigned int uint;
typedef unsigned long long ull;
inline void file(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
namespace IO{
    #define BUF_SIZE (1<<16)
    #define OUT_SIZE (1<<16)
    bool IOerror=0;
    inline char nc(){static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;if(p1==pend){p1=buf;pend=buf+fread(buf,1,BUF_SIZE,stdin);if(pend==p1)return IOerror=1,-1;}return *p1++;}
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline void read(int &x){bool sign=0;char ch=nc();x=0;for(;blank(ch);ch=nc());if(IOerror)return;if(ch=='-')sign=1,ch=nc();for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';if(sign)x=-x;}
    inline void read(ll &x){bool sign=0;char ch=nc();x=0;for(;blank(ch);ch=nc());if(IOerror)return;if(ch=='-')sign=1,ch=nc();for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';if(sign)x=-x;}
    inline void read(double &x){bool sign=0;char ch=nc();x=0;for(;blank(ch);ch=nc());if(IOerror)return;if(ch=='-')sign=1,ch=nc();for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';if(ch=='.'){double tmp=1;ch=nc();for(;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');}if(sign)x=-x;}
    inline void read(char *s){char ch=nc();for(;blank(ch);ch=nc());if(IOerror)return;for(;!blank(ch)&&!IOerror;ch=nc())*s++=ch;*s=0;}
    inline void read(char &c){for(c=nc();blank(c);c=nc());if(IOerror){c=-1;return;}}
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        inline void out(char ch){if(p1==pend){fwrite(buf,1,BUF_SIZE,stdout);p1=buf;}*p1++=ch;}
        inline void print(int x){static char s[15],*s1;s1=s;if(!x)*s1++='0';if(x<0)out('-'),x=-x;while(x)*s1++=x%10+'0',x/=10;while(s1--!=s)out(*s1);}
        inline void println(int x){print(x);out('\n');}
        inline void print(ll x){static char s[25],*s1;s1=s;if(!x)*s1++='0';if(x<0)out('-'),x=-x;while(x)*s1++=x%10+'0',x/=10;while(s1--!=s)out(*s1);}
        inline void println(ll x){print(x);out('\n');}
        inline void print(double x,int y){//y<18
			static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if(x<-1e-12)out('-'),x=-x;x*=mul[y];ll x1=(ll)floor(x);if(x-floor(x)>=0.5)++x1;ll x2=x1/mul[y],x3=x1-x2*mul[y];print(x2);if(y>0){out('.');for(size_t i=1;ib?a:b;}
	inline ll max(const ll &a,const ll &b){return a>b?a:b;}
	inline double max(const double &a,const double &b){return a>b?a:b;}
	inline int min(const int &a,const int &b){return aa)a=b;}
	inline void chkmax(ll &a,const ll &b){if(b>a)a=b;}
	inline void chkmax(double &a,const double &b){if(b>a)a=b;}
	inline void chkmin(int &a,const int &b){if(b=mod?x-mod:x;}
	inline int madd(const int &x,const int &y){return x+y>=1,a=(ll)a*a%mod)if(k&1)s=(ll)s*a%mod;return s;}
	inline void _init(int n){
		ni[1]=1;
		for(int i=2;i<=n;++i) ni[i]=mod-(ll)ni[mod%i]*(mod/i)%mod;
		mul[0]=invmul[0]=1;
		for(int i=1;i<=n;++i) mul[i]=(ll)mul[i-1]*i%mod;
		invmul[n]=qpow(mul[n],mod-2);
		for(int i=n-1;i;--i) invmul[i]=(ll)invmul[i+1]*(i+1)%mod;
	}
	inline int C(int n,int m){if(m>n)return 0;return (ll)mul[n]*invmul[m]%mod*invmul[n-m]%mod;}
	#undef N
}

数论

极速行列式

模数为质数

点击查看代码
inline int det(int n){
	int res=1;bool flag=0;
	for(int j=1;j<=n;++j){
		if(!a[j][j]){
			for(int i=j+1;i<=n;++i)
				if(a[i][j]){std::swap(a[i],a[j]);flag^=1;break;}
		}
		if(!a[j][j]) return 0;
		res=(ll)res*a[j][j]%mod;
		int tmp=qpow(a[j][j],mod-2);
		for(int k=j;k<=n;++k) a[j][k]=(ll)a[j][k]*tmp%mod;
		for(int i=j+1;i<=n;++i){
			tmp=mod-a[i][j];
			for(int k=j;k<=n;++k) modadd(a[i][k],(ll)tmp*a[j][k]%mod);
		}
	}
	return flag?mod-res:res;
}

模数不为质数

点击查看代码
inline int det(int a[N][N],int n){
	int res=1;bool flag=0;
	for(int i=1;i<=n;++i)
		for(int j=i+1;j<=n;++j)
			while(a[j][i]){
				int tmp=a[i][i]/a[j][i];
				for(int k=i;k<=n;++k) moddel(a[i][k],(ll)tmp*a[j][k]%mod);
				std::swap(a[i],a[j]);flag^=1;
			}
	for(int i=1;i<=n;++i) res=(ll)res*a[i][i]%mod;
	if(!res) return 0;
	return flag?mod-res:res;
}

my poly

点击查看代码
namespace poly{
const int G=3,Gi=qpow(G,mod-2);
inline void poly_det(int n,int *a,int *b){for(int i=1;i>1]>>1)|((i&1)<<(l-1));
	for(int i=0;i>1]>>1)|((i&1)?l:0);
		for(int i=0;i

字符串

manacher

点击查看代码
int manacher(){
	rint mx=0,id=0,ans=0;
	for(rint i=1;i<=n;++i){
		if(imx) mx=i+l[i],id=i; 
		ans=max(ans,l[i]);
	}
	return ans-1;
}

KMP

点击查看代码
#include
#include
#include
using namespace std;
const int N=1e6+13;
char s[N],t[N];
int n,m,nxt[N];
inline void init(){
	nxt[1]=0;
	for(int i=2,j=0;i<=n;++i){
		while(j&&t[j+1]!=t[i]) j=nxt[j];
		if(t[j+1]==t[i]) ++j;
		nxt[i]=j;
	}
}
inline void KMP(){
	for(int i=1,j=0;i<=m;++i){
		while(j&&t[j+1]!=s[i]) j=nxt[j];
		if(t[j+1]==s[i]) ++j;
		if(j==n) printf("%d\n",i-n+1),j=nxt[j];
	}
}
int main(){
	scanf("%s",s+1);m=strlen(s+1);
	scanf("%s",t+1);n=strlen(t+1);
	init();
	KMP();
	for(int i=1;i<=n;++i) printf("%d ",nxt[i]);
	return 0;
} 

ACAM

点击查看代码
struct Aho_Corasick_Automaton{
	#define ACA Aho_Corasick_Automaton
	int ch[N][30],fail[N],val[N],cnt;
	ACA(){cnt=0;}
	inline void ins(char *s){
		int len=strlen(s),now=0;
		for(int i=0;iq;fail[0]=0;
		for(int c=0;c<26;++c){
			int u=ch[0][c];
			if(u) fail[ch[0][c]]=0,q.push(ch[0][c]);
		}
		while(!q.empty()){
			int u=q.front();q.pop();
			for(int c=0;c<26;++c){
				if(ch[u][c]) fail[ch[u][c]]=ch[fail[u]][c],q.push(ch[u][c]);
				else ch[u][c]=ch[fail[u]][c];
			}
		}
	}
	inline int query(char *s){
		int n=strlen(s),now=0,res=0;
		for(int i=0;i

exKMP

点击查看代码
#include
#include
#include
using namespace std;
const int N=2e7+13;
char s[N],t[N];
int n,m,nxt[N],ext[N];
inline void init(){
	nxt[1]=n;
	for(int i=2,l=0,r=0;i<=n;++i){
		int tmp=nxt[i-l+1];
		if(i<=r){
			if(i+tmp<=r) nxt[i]=tmp;
			else nxt[i]=r-i+1;	
		}
		while(i+nxt[i]<=n&&t[i+nxt[i]]==t[1+nxt[i]]) ++nxt[i];
		if(i+nxt[i]-1>r) r=i+nxt[i]-1,l=i;
	}
}
inline void exKMP(){
	for(int i=1,l=0,r=0;i<=m;++i){
		int tmp=nxt[i-l+1];
		if(i<=r){
			if(i+tmp<=r) ext[i]=tmp;
			else ext[i]=r-i+1;	
		}
		while(i+ext[i]<=m&&1+ext[i]<=n&&s[i+ext[i]]==t[1+ext[i]]) ++ext[i];
		if(i+ext[i]-1>r) r=i+ext[i]-1,l=i;
	}
}
inline void file(){
	freopen("P5410_1.in","r",stdin);
	freopen("P5410.out","w",stdout);
}
int main(){
	//file();
	scanf("%s%s",s+1,t+1);
	m=strlen(s+1),n=strlen(t+1);
	init();
	exKMP();
	long long ans1=0,ans2=0;
	for(int i=1;i<=n;++i) ans1^=1ll*i*(nxt[i]+1);
	for(int i=1;i<=m;++i) ans2^=1ll*i*(ext[i]+1);
	printf("%lld\n%lld\n",ans1,ans2);
	return 0;
}

SAM

点击查看代码
inline int newpos(std::array nson,int nlen){return ++ptot,len[ptot]=nlen,swap(son[ptot],nson),ptot;}
inline void insert(int c){
	int p=lastpos;int u=newpos(boom,len[p]+1);cnt[u]=1;
	while(p&&!son[p][c]) son[p][c]=u,p=nxt[p];
	if(!p) return lastpos=u,nxt[u]=1,void();
	int d=son[p][c];
	if(len[d]==len[p]+1) nxt[u]=d;
	else{
		int v=newpos(son[d],len[p]+1);
		nxt[v]=nxt[d],nxt[d]=v,nxt[u]=v;
		while(p&&son[p][c]==d) son[p][c]=v,p=nxt[p];
	}
	lastpos=u;
}

图论

网络流

最大流

点击查看代码
const int N=10000+13;
struct Edge{int v,w,nxt;}e[N*5];
int n,m,s,t,lim,to[N],xx[N],yy[N],uu[N],vv[N],deg[N],h[N],tot=1,ad[N];
inline void add(int u,int v,int w){
	e[++tot]=(Edge){v,w,h[u]};h[u]=tot;
	e[++tot]=(Edge){u,0,h[v]};h[v]=tot;
}
int dep[N],cur[N];
bool vis[N];
inline bool bfs(){
	memset(dep,0x7f,sizeof(dep));
	memcpy(cur,h,sizeof(h));
	memset(vis,0,sizeof(vis));
	std::queueq;
	q.push(t),dep[t]=0,vis[t]=1;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=h[u];i;i=e[i].nxt){
			int v=e[i].v,w=e[i^1].w;
			if(!vis[v]&&w) dep[v]=dep[u]+1,vis[v]=1,q.push(v);
		}
	}
	return vis[s];
}
ll dfs(int u,ll minw){
	if(u==t||!minw) return minw;
	ll f,flow=0;
	for(int i=cur[u];i;i=e[i].nxt){
		cur[u]=i;
		int v=e[i].v,w=e[i].w;
		if(dep[u]==dep[v]+1&&(f=dfs(v,min(minw,(ll)w)))){
			minw-=f,flow+=f,e[i].w-=f,e[i^1].w+=f;
			if(!minw) break;
		}
	}
	return flow;
}
inline ll dinic(){
	ll flow=0;
	while(bfs()) flow+=dfs(s,INF);
	return flow;
}
int main(){
	read(n),read(m),read(s),read(t); 
	for(int i=1;i<=m;i++){
		int u,v,w;read(u),read(v),read(w);
		add(u,v,w);
		add(v,u,0);
	}
	println(dinic());
	return 0;
}

费用流

点击查看代码
#include
#include
#include
#include
#define re register
using namespace std;
const int N=5000+21,M=50000+21,INF=0x3f3f3f3f;
struct Edge{int u,v,f,w,nxt;}e[M*2];
int h[N],dist[N],last[N],flow[N],pre[N];
bool vis[N];
int n,m,s,t,tot=1;
inline void add(re int u,re int v,re int f,re int w){
	e[++tot]=(Edge){u,v,f,w,h[u]};
	h[u]=tot;
}
bool spfa(){
	memset(dist,0x3f,sizeof(dist));
	memset(vis,0,sizeof(vis));
	memset(flow,0x3f,sizeof(flow));
	pre[t]=-1;
	queueq;
	q.push(s);
	vis[s]=1;
	dist[s]=0;
	while(!q.empty()){
		re int u=q.front();
		q.pop();
		vis[u]=0;
		for(re int i=h[u];i;i=e[i].nxt){
			re int v=e[i].v,w=e[i].w,f=e[i].f;
			if(f&&dist[v]>dist[u]+w){
				dist[v]=dist[u]+w;
				flow[v]=min(flow[u],f);
				pre[v]=u;
				last[v]=i;
				if(!vis[v]){
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
	return pre[t]!=-1;
}
void mcmf(){
	re int maxflow=0,mincost=0;
	while(spfa()){
		maxflow+=flow[t];
		mincost+=flow[t]*dist[t];
		re int now=t;
		while(now!=s){
			e[last[now]].f-=flow[t];
			e[last[now]^1].f+=flow[t];
			now=pre[now];
		}
	}
	printf("%d %d\n",maxflow,mincost);
}
int main(){
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(re int i=1;i<=m;++i){
		re int u,v,f,w;
		scanf("%d%d%d%d",&u,&v,&f,&w);
		add(u,v,f,w);
		add(v,u,0,-w);
	}
	mcmf();
	return 0;
}

数据结构

LCT

点击查看代码
#include
#include
using namespace std;
const int N=1e5+13;
inline void swap(int &x,int &y){x^=y^=x^=y;}
int n,m,a[N];
struct Link_Cut_Tree{
	struct Stack{
		int s[N],t;
		inline void clear(){t=0;}
		Stack(){clear();}
		inline void push(int x){s[++t]=x;}
		inline int top(){return s[t];}
		inline void pop(){--t;}
		inline bool empty(){return !t;}
	};
	int fa[N],val[N],ch[N][2];bool tag[N];
	inline void refresh(int x){val[x]=a[x]^val[ch[x][0]]^val[ch[x][1]];}
	inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
	inline bool chk(int x){return ch[fa[x]][1]==x;}
	inline void rotate(int x){
		int f=fa[x],gf=fa[f],k=chk(x),w=ch[x][k^1];
		fa[x]=gf;if(!isroot(f)) ch[gf][chk(f)]=x;
		if(w) fa[w]=f;ch[f][k]=w;
		fa[f]=x;ch[x][k^1]=f;
		refresh(f),refresh(x);
	}
	inline void pushdown(int x){
		if(!tag[x]) return;
		tag[ch[x][0]]^=1,tag[ch[x][1]]^=1,tag[x]=0;
		swap(ch[x][0],ch[x][1]);
	}
	inline void splay(int x){
		Stack st;
		int p=x;
		while(!isroot(p)) st.push(p),p=fa[p];
		st.push(p);
		while(!st.empty()) pushdown(st.top()),st.pop();
		while(!isroot(x)){
			int f=fa[x],gf=fa[f];
			if(!isroot(f)){
				if(chk(f)==chk(x)) rotate(f);
				else rotate(x);
			}
			rotate(x);
		}
	}
	inline void access(int x){
		for(int p=0;x;p=x,x=fa[x]) splay(x),ch[x][1]=p,refresh(x);
	}
	inline void makeroot(int x){
		access(x);
		splay(x);
		tag[x]^=1;
	}
	inline int findroot(int x){
		access(x);
		splay(x);
		while(ch[x][0]) x=ch[x][0];
		return x;
	}
	inline void split(int x,int y){
		makeroot(x);
		access(y);
		splay(y);
	}
	inline void link(int x,int y){
		makeroot(x);
		if(findroot(y)!=x) fa[x]=y;
	}
	inline void cut(int x,int y){
		split(x,y);
		if(ch[y][0]==x&&!ch[x][1]) fa[x]=ch[y][0]=0;
	}
	inline void modify(int x,int y){
		access(x);
		splay(x);
		a[x]=y,refresh(x);
	}
}T;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]);
	while(m--){
		int op,x,y;
		scanf("%d%d%d",&op,&x,&y);
		switch(op){
			case 0:{T.split(x,y);printf("%d\n",T.val[y]);break;}
			case 1:{T.link(x,y);break;}
			case 2:{T.cut(x,y);break;}
			case 3:{T.modify(x,y);break;}
		}
	}
	return 0;
}

fhqtreap

点击查看代码
#include
#include
#include
#include
inline int rd(){
	int res=0,flag=1;char c=getchar();
	for(;!isdigit(c);c=getchar())if(c=='-')flag=-1;
	for(;isdigit(c);c=getchar())res=(res<<1)+(res<<3)+(c-'0');
	return res*flag;
}
void wt(int x){if(x<0)putchar('-'),x=-x;if(x>9)wt(x/10);putchar(x%10+'0');}
std::mt19937 rnd(std::chrono::system_clock::now().time_since_epoch().count());
const int N=1e5+13;
int n,rt,tot;
struct Fhqtreap{int ls,rs,siz,val,prio;}t[N];
#define ls(p) t[p].ls
#define rs(p) t[p].rs
inline int newnode(int x){return t[++tot]=(Fhqtreap){0,0,1,x,(int)rnd()},tot;}
inline void refresh(int p){t[p].siz=t[ls(p)].siz+t[rs(p)].siz+1;}
int merge(int p,int q){
	if(!p||!q) return p|q;
	if(t[p].priot[ls(p)].siz+1) k-=t[ls(p)].siz+1,p=rs(p);
		else return p;
	}
}
int main(){
//	freopen("P3369_6.in","r",stdin);
//	freopen("P3369.out","w",stdout);
	int T=rd();
	while(T--){
		int op=rd(),k=rd(),x,y,z;
		switch(op){
			case 1:{
				split(rt,k,x,y);
				rt=merge(merge(x,newnode(k)),y);
				break;
			}
			case 2:{
				split(rt,k-1,x,z);split(z,k,z,y);
				rt=merge(merge(x,merge(ls(z),rs(z))),y);
				break;
			}
			case 3:{
				split(rt,k-1,x,y);
				wt(t[x].siz+1),putchar('\n');
				rt=merge(x,y);
				break;
			}
			case 4:{
				wt(t[kth(rt,k)].val),putchar('\n');
				break;
			}
			case 5:{
				split(rt,k-1,x,y);
				wt(t[kth(x,t[x].siz)].val),putchar('\n');
				rt=merge(x,y);
				break;
			}
			case 6:{
				split(rt,k,x,y);
				wt(t[kth(y,1)].val),putchar('\n');
				rt=merge(x,y);
				break;
			}
		}
	}
	return 0;
}

可持久化fhqtreap

点击查看代码
#include
#include
#include
#include
using namespace std;
const int N=5e5+13,logN=40+13;
int INF=2147483647;
struct Fhqtreap{int siz,ls,rs,prio,val;}t[N*logN];
typedef Fhqtreap Fhq;
int n,tot,rt[N];
inline int newnode(int v){t[++tot]=(Fhq){1,0,0,rand(),v};return tot;}
inline void refresh(int p){t[p].siz=t[t[p].ls].siz+t[t[p].rs].siz+1;}
int merge(int p,int q){
	if(!p||!q) return p+q;
	int now=++tot;
	if(t[p].priot[t[p].ls].siz+1) k-=t[t[p].ls].siz+1,p=t[p].rs;
		else return p;
	}
}
int main(){
	srand(time(NULL));
	scanf("%d",&n);
	for(int i=1,v,op,k,x,y,z;i<=n;++i,x=y=z=0){
		scanf("%d%d%d",&v,&op,&k);rt[i]=rt[v];
		switch(op){
			case 1:{
				split(rt[i],k,x,y);
				rt[i]=merge(merge(x,newnode(k)),y);
				break;
			}
			case 2:{
				split(rt[i],k,x,z);
				split(x,k-1,x,y);
				y=merge(t[y].ls,t[y].rs);
				rt[i]=merge(merge(x,y),z);
				break;
			}
			case 3:{
				split(rt[i],k-1,x,y);
				printf("%d\n",t[x].siz+1);
				rt[i]=merge(x,y);
				break;
			}
			case 4:{
				printf("%d\n",t[kth(rt[i],k)].val);
				break;
			}
			case 5:{
				split(rt[i],k-1,x,y);
				if(!x) printf("%d\n",-INF);
				else printf("%d\n",t[kth(x,t[x].siz)].val);
				rt[i]=merge(x,y);
				break;
			}
			case 6:{
				split(rt[i],k,x,y);
				if(!y) printf("%d\n",INF);
				else printf("%d\n",t[kth(y,1)].val);
				rt[i]=merge(x,y);
				break;
			}
		}
	}
	return 0;
}

笛卡尔树

点击查看代码
#include
#include
#define rint register int
using namespace std;
inline int rd(){
	int res=0;char c=getchar();
	for(;!isdigit(c);c=getchar());
	for(;isdigit(c);c=getchar())res=(res<<1)+(res<<3)+(c-'0');
	return res;
}
const int N=1e7+13;
int n,a[N],s[N],top,L[N],R[N];
int main(){
	n=rd();
	for(rint i=1;i<=n;++i){
		a[i]=rd();rint pos=top;
		while(pos&&a[s[pos]]>a[i]) --pos;
		if(pos) R[s[pos]]=i;
		if(pos

虚树

点击查看代码
inline void build(){
	st.clear();Tot=0;
	sort(a+1,a+k+1,cmp);
	st.push(1);
	for(int i=1;i<=k;++i){
		int t=lca(a[i],st.top());
		if(t!=st.top()){
			while(st.t>1&&id[t]

Segmenttree beats

点击查看代码
#include
#include
using namespace std;
typedef long long ll;
inline int max(const int &a,const int &b){return a>b?a:b;}
inline int min(const int &a,const int &b){return a9)wt(x/10);putchar(x%10+'0');}
const int N=5e5+13,INF=0x3f3f3f3f;
struct SegTree{int l,r,maxx,premax,se,cnt,add,preadd,addmax,preaddmax;ll sum;}t[N<<2];
int n,m;
#define ls p<<1
#define rs p<<1|1
#define mid ((t[p].l+t[p].r)>>1)
inline void refresh(int p){
	t[p].sum=t[ls].sum+t[rs].sum;
	t[p].premax=max(t[ls].premax,t[rs].premax);
	if(t[ls].maxx>t[rs].maxx) t[p].maxx=t[ls].maxx,t[p].cnt=t[ls].cnt,t[p].se=max(t[ls].se,t[rs].maxx);
	else if(t[ls].maxx==t[rs].maxx) t[p].maxx=t[ls].maxx,t[p].cnt=t[ls].cnt+t[rs].cnt,t[p].se=max(t[ls].se,t[rs].se);
	else t[p].maxx=t[rs].maxx,t[p].cnt=t[rs].cnt,t[p].se=max(t[ls].maxx,t[rs].se);
}
void build(int p,int l,int r){
	t[p].l=l,t[p].r=r;
	if(l==r){t[p].sum=t[p].maxx=t[p].premax=rd(),t[p].se=-INF,t[p].cnt=1;return;}
	build(ls,l,mid);build(rs,mid+1,r);
	refresh(p);
}
inline void pushup(int p,int x,int px,int x_m,int px_m){
	t[p].sum+=1ll*t[p].cnt*x_m+1ll*(t[p].r-t[p].l+1-t[p].cnt)*x;
	t[p].premax=max(t[p].premax,t[p].maxx+px_m);
	t[p].preadd=max(t[p].preadd,t[p].add+px);
	t[p].preaddmax=max(t[p].preaddmax,t[p].addmax+px_m);
	t[p].add+=x,t[p].addmax+=x_m,t[p].maxx+=x_m;
	if(t[p].se!=-INF) t[p].se+=x;
}
inline void pushdown(int p){
	int tmp=max(t[ls].maxx,t[rs].maxx);
	if(t[ls].maxx==tmp) pushup(ls,t[p].add,t[p].preadd,t[p].addmax,t[p].preaddmax);
	else pushup(ls,t[p].add,t[p].preadd,t[p].add,t[p].preadd);
	if(t[rs].maxx==tmp) pushup(rs,t[p].add,t[p].preadd,t[p].addmax,t[p].preaddmax);
	else pushup(rs,t[p].add,t[p].preadd,t[p].add,t[p].preadd);
	t[p].add=t[p].preadd=t[p].addmax=t[p].preaddmax=0;
}
void update(int p,int l,int r,int x){
	if(l<=t[p].l&&t[p].r<=r) return pushup(p,x,x,x,x);
	pushdown(p);
	if(l<=mid) update(ls,l,r,x);
	if(r>mid) update(rs,l,r,x);
	refresh(p);
}
void modify(int p,int l,int r,int x){
	if(x>=t[p].maxx) return;
	if(l<=t[p].l&&t[p].r<=r&&x>t[p].se) return pushup(p,0,0,x-t[p].maxx,x-t[p].maxx);
	pushdown(p);
	if(l<=mid) modify(ls,l,r,x);
	if(r>mid) modify(rs,l,r,x);
	refresh(p);
}
ll query_sum(int p,int l,int r){
	if(l<=t[p].l&&t[p].r<=r) return t[p].sum;
	pushdown(p);ll res=0;
	if(l<=mid) res+=query_sum(ls,l,r);
	if(r>mid) res+=query_sum(rs,l,r);
	return res;
}
int query_max(int p,int l,int r){
	if(l<=t[p].l&&t[p].r<=r) return t[p].maxx;
	pushdown(p);int res=-INF;
	if(l<=mid) res=max(res,query_max(ls,l,r));
	if(r>mid) res=max(res,query_max(rs,l,r));
	return res;
}
int query_premax(int p,int l,int r){
	if(l<=t[p].l&&t[p].r<=r) return t[p].premax;
	pushdown(p);int res=-INF;
	if(l<=mid) res=max(res,query_premax(ls,l,r));
	if(r>mid) res=max(res,query_premax(rs,l,r));
	return res;
}
inline void file(){
	freopen("P6242_1.in","r",stdin);
	freopen("P6242.out","w",stdout);
}
int main(){
	//file();
	n=rd(),m=rd();
	build(1,1,n);
	while(m--){
		int op,l,r,x;
		op=rd(),l=rd(),r=rd();
		switch(op){
			case 1:x=rd();update(1,l,r,x);break;
			case 2:x=rd();modify(1,l,r,x);break;
			case 3:printf("%lld\n",query_sum(1,l,r));break;
			case 4:printf("%d\n",query_max(1,l,r));break;
			case 5:printf("%d\n",query_premax(1,l,r));break;
		}
	}
	return 0;
}

李超树

点击查看代码
#include
#include
#include
using namespace std;
const int N=40000+13,M=1e5+13;
const double eps=1e-10;
struct Segment{double k,b;}a[M];
struct Node{
	int id;double y;
	bool operator<(const Node &a)const{
		if(fabs(y-a.y)a.id;
		return y>1)
void build(int p,int l,int r){
	t[p].l=l,t[p].r=r;
	if(l==r) return;
	build(ls,l,mid);build(rs,mid+1,r);
}
void update(int p,int l,int r,int id){
	if(l<=t[p].l&&t[p].r<=r){
		if(!t[p].id){t[p].id=id;return;}
		if(t[p].l==t[p].r){
			if(val(id,t[p].l)>val(t[p].id,t[p].l)) t[p].id=id;
			return;
		}
		if(fabs(a[id].k-a[t[p].id].k)val(t[p].id,mid)) t[p].id=id;
		}
		else if(a[id].k>a[t[p].id].k){
			if(val(id,mid)>val(t[p].id,mid)){
				update(ls,l,r,t[p].id);
				t[p].id=id;
			}
			else update(rs,l,r,id);
		}
		else{
			if(val(id,mid)>val(t[p].id,mid)){
				update(rs,l,r,t[p].id);
				t[p].id=id;
			}
			else update(ls,l,r,id);
		}
		return;
	}
	if(l<=mid) update(ls,l,r,id);
	if(r>mid) update(rs,l,r,id);
}
Node query(int p,int x){
	Node res=(Node){t[p].id,val(t[p].id,x)};
	if(t[p].l==t[p].r) return res;
	return max(res,x<=mid?query(ls,x):query(rs,x));
}
int main(){
	//freopen("P4097_1.in.txt","r",stdin);
	//freopen("P4097.out","w",stdout);
	build(1,1,n);
	scanf("%d",&m);int lastans=0;
	while(m--){
		int op,x0,y0,x1,y1,x;
		scanf("%d",&op);
		if(op){
			scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
			x0=(x0+lastans-1)%n+1,x1=(x1+lastans-1)%n+1;
			y0=(y0+lastans-1)%lim+1,y1=(y1+lastans-1)%lim+1;
			if(x0>x1) swap(x0,x1),swap(y0,y1);
			int id=add(x0,y0,x1,y1);
			update(1,x0,x1,id);
		}
		else{
			scanf("%d",&x);x=(x+lastans-1)%n+1;
			Node ans=query(1,x);
			printf("%d\n",(lastans=ans.id));
		}
	}
	return 0;
}