板子合集
meyi 队长火车头
点击查看代码
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)
切队长火车头
点击查看代码
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
my 缺省源
点击查看代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#include<map>
#include<bitset>
#include<set>
#include<unordered_map>
#include<random>
#include<chrono>
#include<deque>
#include<cassert>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<vector>
#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<int,int> 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;i<y&&x3*mul[i]<mul[y];out('0'),++i);print(x3);}
}
inline void println(double x,int y){print(x,y);out('\n');}
inline void print(char *s){while(*s)out(*s++);}
inline void println(char *s){while(*s)out(*s++);out('\n');}
inline void flush(){if(p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
~Ostream_fwrite(){flush();}
}Ostream;
inline void print(int x){Ostream.print(x);}
inline void println(int x){Ostream.println(x);}
inline void print(char x){Ostream.out(x);}
inline void println(char x){Ostream.out(x);Ostream.out('\n');}
inline void print(ll x){Ostream.print(x);}
inline void println(ll x){Ostream.println(x);}
inline void print(double x,int y){Ostream.print(x,y);}
inline void println(double x,int y){Ostream.println(x,y);}
inline void print(char *s){Ostream.print(s);}
inline void println(char *s){Ostream.println(s);}
inline void println(){Ostream.out('\n');}
inline void flush(){Ostream.flush();}
#undef OUT_SIZE
#undef BUF_SIZE
}using namespace IO;
namespace Little_function{
inline int abs(int x){return x<0?-x:x;}
inline ll abs(ll x){return x<0?-x:x;}
inline double abs(double x){return x<0?-x:x;}
inline int max(const int &a,const int &b){return a>b?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 a<b?a:b;}
inline ll min(const ll &a,const ll &b){return a<b?a:b;}
inline double min(const double &a,const double &b){return a<b?a:b;}
inline void chkmax(int &a,const int &b){if(b>a)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<a)a=b;}
inline void chkmin(ll &a,const ll &b){if(b<a)a=b;}
inline void chkmin(double &a,const double &b){if(b<a)a=b;}
inline void swap(int &x,int &y){x^=y^=x^=y;}
inline void swap(ll &x,ll &y){x^=y^=x^=y;}
inline void swap(double &x,double &y){double t=x;x=y,y=t;}
inline int madd(const int &a,const int &b,const int &p){return (a+b)%p;}
inline int mdel(const int &a,const int &b,const int &p){return (a-b<0?a-b+p:a-b);}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
}using namespace Little_function;
namespace modint{
#define N 200005
const int mod=1e9+7;
int ni[N],mul[N],invmul[N];
inline int md(const int &x){return x>=mod?x-mod:x;}
inline int madd(const int &x,const int &y){return x+y<mod?x+y:x+y-mod;}
inline int mdel(const int &x,const int &y){return x-y<0?x-y+mod:x-y;}
inline void modadd(int &x,const int &y){x=(x+y<mod?x+y:x+y-mod);}
inline void moddel(int &x,const int &y){x=(x-y<0?x-y+mod:x-y);}
inline int qpow(int a,int k){int s=1;for(;k;k>>=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<n;++i) b[i-1]=(ll)i*a[i]%mod;b[n-1]=0;}
inline void poly_int(int n,int *a,int *b){for(int i=0;i<n-1;++i) b[i+1]=(ll)ni[i+1]*a[i]%mod;b[0]=0;}
int r[N];
inline void fft(int *f,int limit,int type){
for(int i=0;i<limit;++i)
if(i<r[i]) swap(f[i],f[r[i]]);
for(int i=1;i<limit;i<<=1){
int Wn=qpow(type==1?G:Gi,(mod-1)/(i<<1));
for(int j=0;j<limit;j+=(i<<1)){
int w=1;
for(int k=0;k<i;++k,w=(ll)w*Wn%mod){
int x=f[j+k],y=(ll)w*f[j+k+i]%mod;
f[j+k]=md(x+y),f[j+k+i]=md(x-y+mod);
}
}
}
if(type==1) return;
int Inv=qpow(limit,mod-2);
for(int i=0;i<limit;++i) f[i]=(ll)f[i]*Inv%mod;
}
inline void poly_mul(int n,int *a,int *b){
static int mul_a[N],mul_b[N];
#define x mul_a
#define y mul_b
int limit=1,l=0;
while(limit<n) limit<<=1,++l;
for(int i=0;i<limit;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
for(int i=0;i<limit;++i) x[i]=a[i],y[i]=b[i];
fft(x,limit,1),fft(y,limit,1);
for(int i=0;i<limit;++i) x[i]=(ll)x[i]*y[i]%mod;
fft(x,limit,-1);
for(int i=0;i<n;++i) a[i]=x[i];
#undef x
#undef y
}
inline void poly_inv(int n,int *a,int *b){
static int inv_a[N];
#define c inv_a
for(int i=0,lim=min(N-1,n<<2);i<lim;++i) b[i]=0;
b[0]=qpow(a[0],mod-2);int l=2;
while(l<(n<<1)){
for(int i=0;i<(l<<1);++i) r[i]=(r[i>>1]>>1)|((i&1)?l:0);
for(int i=0;i<l;++i) c[i]=a[i];
for(int i=l;i<(l<<1);++i) c[i]=0;
fft(c,l<<1,1),fft(b,l<<1,1);
for(int i=0;i<(l<<1);++i) b[i]=(ll)md(2-(ll)b[i]*c[i]%mod+mod)*b[i]%mod;
fft(b,l<<1,-1);
for(int i=l;i<(l<<1);++i) b[i]=0;
l<<=1;
}
#undef c
}
inline void poly_ln(int n,int *a,int *b){
assert(a[0]==1);
static int ln_a[N],ln_b[N];
#define c ln_a
#define d ln_b
poly_det(n,a,c);
poly_inv(n,a,d);
poly_mul(n<<1,c,d);
poly_int(n,c,b);
#undef c
#undef d
}
inline void poly_exp(int n,int *a,int *b){
assert(a[0]==0);
static int exp_a[N],exp_b[N];
#define c exp_a
#define d exp_b
for(int i=0,lim=min(N-1,n<<2);i<lim;++i) b[i]=0;
b[0]=1;int l=2;
while(l<(n<<1)){
poly_ln(l,b,d);
for(int i=0;i<l;++i) c[i]=md(a[i]-d[i]+mod);modadd(c[0],1);
for(int i=l;i<(l<<1);++i) c[i]=0;
poly_mul(l<<1,b,c);
for(int i=l;i<(l<<1);++i) b[i]=0;
l<<=1;
}
#undef c
#undef d
}
inline void poly_div(int n,int m,int *a,int *b,int *p,int *q){
static int div_a[N],div_b[N],div_c[N];
#define c div_a
#define d div_b
#define e div_c
memset(c,0,sizeof c);memset(d,0,sizeof d);memset(e,0,sizeof e);
for(int i=0;i<n;++i) c[i]=a[i];
for(int i=0;i<m;++i) d[i]=b[i];
std::reverse(c,c+n),std::reverse(d,d+m);
poly_inv(n+m,d,e);
poly_mul((n+m)<<1,e,c);
for(int i=0;i<n-m+1;++i) p[i]=e[i];
std::reverse(p,p+n-m+1);std::reverse(c,c+n),std::reverse(d,d+m);
poly_mul(n,d,p);
for(int i=0;i<m;++i) q[i]=md(c[i]-d[i]+mod);
#undef c
#undef d
#undef e
}
}
字符串
manacher
点击查看代码
int manacher(){
rint mx=0,id=0,ans=0;
for(rint i=1;i<=n;++i){
if(i<mx) l[i]=min(l[id*2-i],mx-i);
else l[i]=1;
while(s[i+l[i]]==s[i-l[i]]) ++l[i];
if(i+l[i]>mx) mx=i+l[i],id=i;
ans=max(ans,l[i]);
}
return ans-1;
}
KMP
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
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;i<len;++i){
int c=s[i]-'a';
if(!ch[now][c]) ch[now][c]=++cnt;
now=ch[now][c];
}
val[now]++;
}
inline void build(){
queue<int>q;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<n;++i){
now=ch[now][s[i]-'a'];
for(int j=now;j&&val[j]!=-1;j=fail[j]) res+=val[j],val[j]=-1;
}
return res;
}
}AC;
exKMP
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
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<int,M> 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::queue<int>q;
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<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#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;
queue<int>q;
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<iostream>
#include<cstdio>
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<cstdio>
#include<iostream>
#include<random>
#include<chrono>
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].prio<t[q].prio){
t[p].rs=merge(t[p].rs,q);
refresh(p);
return p;
}
t[q].ls=merge(p,t[q].ls);
refresh(q);
return q;
}
void split(int now,int k,int &p,int &q){
if(!now) return p=q=0,void();
if(t[now].val<=k) p=now,split(rs(now),k,rs(p),q);
else q=now,split(ls(now),k,p,ls(q));
refresh(now);
}
int kth(int p,int k){
while(1){
if(k<=t[ls(p)].siz) p=ls(p);
else if(k>t[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<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
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].prio<t[q].prio){
t[now]=t[p];
t[now].rs=merge(t[now].rs,q);
}
else{
t[now]=t[q];
t[now].ls=merge(p,t[now].ls);
}
refresh(now);return now;
}
void split(int now,int k,int &p,int &q){
if(!now){p=q=0;return;}
if(t[now].val<=k){
t[p=++tot]=t[now];
split(t[p].rs,k,t[p].rs,q);
refresh(p);
}
else{
t[q=++tot]=t[now];
split(t[q].ls,k,p,t[q].ls);
refresh(q);
}
}
inline int kth(int p,int k){
while(1){
if(k<=t[t[p].ls].siz) p=t[p].ls;
else if(k>t[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<iostream>
#include<cstdio>
#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<top) L[i]=s[pos+1];
s[top=(++pos)]=i;
}
long long ans1=0,ans2=0;
for(rint i=1;i<=n;++i) ans1^=1ll*i*(L[i]+1),ans2^=1ll*i*(R[i]+1);
printf("%lld %lld\n",ans1,ans2);
return 0;
}
虚树
点击查看代码
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]<id[st.ttop()]) Add(st.ttop(),st.top()),st.pop();
if(t!=st.ttop()) Add(t,st.top()),st.pop(),st.push(t);
else Add(t,st.top()),st.pop();
}
st.push(a[i]);
}
for(int i=1;i<st.t;++i) Add(st.s[i],st.s[i+1]);
}
Segmenttree beats
点击查看代码
#include<iostream>
#include<cstdio>
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 a<b?a:b;}
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(ll x){if(x>9)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<iostream>
#include<cstdio>
#include<cmath>
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)<eps) return id>a.id;
return y<a.y;
}
};
int n=39989,m,lim=1e9,cnt;
inline int add(int x0,int y0,int x1,int y1){
++cnt;
if(x0==x1) a[cnt].k=0,a[cnt].b=max(y0,y1);
else{
a[cnt].k=1.0*(y1-y0)/(x1-x0);
a[cnt].b=y0-a[cnt].k*x0;
}
return cnt;
}
inline double val(int id,int x){return a[id].k*x+a[id].b;}
struct SegTree{int l,r,id;}t[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid ((t[p].l+t[p].r)>>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)<eps){
if(val(id,mid)>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;
}