一些奇妙的模板。慢慢更新好啦。
目录之外的windows对拍
while (T--)
{
system("rand > rand.in");
system("mthq < rand.in > mthq.out");
system("jvruo < rand.in > jvruo.out");
if (system("fc mthq.out jvruo.out")) break;
}
system("pause");
Linux
while true ; do
./rand > input
./mthq < input > mthq.out
./jvruo < input > jvruo.out
diff mthq.out jvruo.out
if [ $? -ne 0 ] ; then break; fi
done
目录
1.并查集
2.treap
3.高精度乘法(FFT)
4.树链剖分线段树
1.并查集
inline void makeset(int n){
for(int i=1;i<=n;i++)fa[i]=i;
}
inline int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
inline union_set(int x,int y){
if((x=find(x))==(y=find(y)))return;
if(rk[x]>rk[y])fa[y]=x;
else {
fa[x]=y;
if(rk[x]==rk[y])rk[y]++;
}
}
2.treap
#define mp make_pair
typedef pair<int,int>par;
int my_rand(){
static int seed=623;
return seed=int(seed*48271LL%2147483647);
}
struct treap{
int rt,cnt;
int lson[MAXN],rson[MAXN],w[MAXN],prio[MAXN],size[MAXN],sum[MAXN],amax[MAXN],lmax[MAXN],rmax[MAXN];
int fz[MAXN],fg[MAXN];
bool lzt[MAXN];
inline void pushup(int p){
if(!p)return;
int l=lson[p],r=rson[p];
size[p]=size[l]+size[r]+1;
sum[p]=sum[l]+sum[r]+w[p];
lmax[p]=max(lmax[l],sum[l]+w[p]+max(0,lmax[r]));
rmax[p]=max(rmax[r],sum[r]+w[p]+max(0,rmax[l]));
amax[p]=max(w[p]+max(0,rmax[l])+max(0,lmax[r]),max(amax[l],amax[r]));
}
inline void flip(int p){
if(!p)return;
fz[p]^=1;swap(lmax[p],rmax[p]);
}
inline void mark(int p,int c){
if(!p)return;
w[p]=c;sum[p]=size[p]*c;
lmax[p]=rmax[p]=amax[p]=max(size[p]*c,c);
lzt[p]=1;
}
inline void pushdown(int p){
if(!p)return;
if(fz[p]){
fz[p]^=1;
flip(lson[p]);
flip(rson[p]);
swap(lson[p],rson[p]);
}
if(lzt[p]){
mark(lson[p],w[p]);
mark(rson[p],w[p]);
lzt[p]=0;
}
}
par split(int p,int x){
if(!x)return mp(0,p);
pushdown(p);
int l=lson[p],r=rson[p];
if(x==size[l]){
lson[p]=0;pushup(p);return mp(l,p);
}
if(x==size[l]+1){
rson[p]=0;pushup(p);return mp(p,r);
}
if(x<size[l]){
par tem=split(l,x);
lson[p]=tem.second;pushup(p);return mp(tem.first,p);
}
par tem=split(r,x-size[l]-1);
rson[p]=tem.first;pushup(p);return mp(p,tem.second);
}
int merge(int x,int y){
if(!x){pushup(y);return y;}
if(!y){pushup(x);return x;}
pushdown(x);pushdown(y);
if(prio[x]<prio[y]){
rson[x]=merge(rson[x],y);pushup(x);return x;
}
else {
lson[y]=merge(x,lson[y]);pushup(y);return y;
}
}
inline void newnode(int p,int x){
lson[p]=rson[p]=0;w[p]=sum[p]=amax[p]=lmax[p]=rmax[p]=x;
prio[p]=my_rand();size[p]=1;fz[p]=fg[p]=0;lzt[p]=0;
}
}T;
queue<int>q;
int sta[MAXN],tp;
int build(int n){
tp=0;
int pre,tmp,dq;
for(int i=1;i<=n;i++){
pre=0;
scanf("%d",&tmp);
if(q.size())dq=q.front(),q.pop();
else dq=++T.cnt;
T.newnode(dq,tmp);
while(tp&&T.prio[sta[tp]]>T.prio[dq]){
pre=sta[tp--];T.pushup(pre);
}
if(tp)T.rson[sta[tp]]=dq;
T.lson[dq]=pre;
sta[++tp]=dq;
}
while(tp)T.pushup(sta[tp--]);
return sta[1];
}
void cun(int p){
if(!p)return;
q.push(p);
cun(T.lson[p]);
cun(T.rson[p]);
}
void ins(){
int pos,n;
scanf("%d%d",&pos,&n);
par tem=T.split(T.rt,pos);
T.rt=T.merge(tem.first,T.merge(build(n),tem.second));
}
void del(){
int pos,n;
scanf("%d%d",&pos,&n);
par tem=T.split(T.rt,pos-1);
par tem2=T.split(tem.second,n);
cun(tem2.first);
T.rt=T.merge(tem.first,tem2.second);
}
void get(){
int pos,n;
scanf("%d%d",&pos,&n);
par tem=T.split(T.rt,pos-1);
par tem2=T.split(tem.second,n);
printf("%d\n",T.sum[tem2.first]);
T.rt=T.merge(tem.first,T.merge(tem2.first,tem2.second));
}
void rev(){
int pos,n;
scanf("%d%d",&pos,&n);
par tem=T.split(T.rt,pos-1);
par tem2=T.split(tem.second,n);
T.flip(tem2.first);
T.rt=T.merge(tem.first,T.merge(tem2.first,tem2.second));
}
void sam(){
int pos,n,c;
scanf("%d%d%d",&pos,&n,&c);
par tem=T.split(T.rt,pos-1);
par tem2=T.split(tem.second,n);
T.mark(tem2.first,c);
T.rt=T.merge(tem.first,T.merge(tem2.first,tem2.second));
}
3.高精度乘法(FFT)
#include<bits/stdc++.h>
using namespace std;
const double Pi=acos(-1);
const int MAXN=150000;
struct cp{
double x,y;
cp (double xx=0,double yy=0){x=xx,y=yy;}
}a[MAXN],b[MAXN];
cp operator +(cp a,cp b){
return cp(a.x+b.x,a.y+b.y);
}
cp operator -(cp a,cp b){
return cp(a.x-b.x,a.y-b.y);
}
cp operator *(cp a,cp b){
return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
int limit=1,n,l,r[MAXN];
void FFT(cp*A,int ty){
for(int i=0;i<limit;i++)
if(i<r[i])swap(A[i],A[r[i]]);
for(int mid=1;mid<limit;mid<<=1){
cp Wn(cos(Pi/mid),ty*sin(Pi/mid));
int R=mid<<1;
for(int j=0;j<limit;j+=R){
cp W(1,0);
for(int k=0;k<mid;k++){
cp x=A[j+k],y=W*A[j+mid+k];
A[j+k]=x+y;
A[j+mid+k]=x-y;
W=W*Wn;
}
}
}
}
int output[150000];
char orza[60005],orzb[60005];
int main(){
scanf("%d",&n);
n--;
scanf("%s%s",orza,orzb);
for(int i=0;i<=n;i++)
a[i].x=orza[i]-'0';
for(int i=0;i<=n;i++)
b[i].x=orzb[i]-'0';
while(limit<=n+n)limit<<=1,l++;
for(int i=0;i<limit;i++){
r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
}
FFT(a,1);
FFT(b,1);
for(int i=0;i<=limit;i++)a[i]=a[i]*b[i];
FFT(a,-1);
int pre=0;
for(int i=limit;i>=0;i--){
if(i>0){
output[i]+=(int)(a[i].x/limit+0.5);
output[i-1]+=output[i]/10;output[i]%=10;
}
else {
output[i]+=(int)(a[i].x/limit+0.5);
pre+=output[i]/10;output[i]%=10;
}
}
bool flag=0;
if(pre){
flag=1;
printf("%d",pre);
}
for(int i=0;i<=n+n;i++){
if(output[i]!=0){
printf("%d",output[i]);
flag=1;
}
else if(flag){
printf("0");
}
}
}
4.树链剖分线段树
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
typedef long long ll;
ll MOD;
struct edge{
ll to,next;
}e[MAXN<<1];
ll head[MAXN],cnt=0;
inline void add(ll u,ll v){
e[++cnt]=(edge){v,head[u]},head[u]=cnt;
e[++cnt]=(edge){u,head[v]},head[v]=cnt;
}
ll size[MAXN],dep[MAXN],hson[MAXN],fa[MAXN];
void dfs(ll u,ll father){
size[u]=1;
dep[u]=dep[father]+1;
fa[u]=father;
for(ll i=head[u];i;i=e[i].next){
ll v=e[i].to;
if(v==father)continue;
dfs(v,u);
size[u]+=size[v];
if(!hson[u]||size[hson[u]]<size[v])hson[u]=v;
}
}
ll top[MAXN],id[MAXN],rl[MAXN],tim=0,a[MAXN],n,m,r;
void dfs2(ll u,ll tp){
top[u]=tp;
id[u]=++tim;
rl[tim]=u;
if(hson[u])dfs2(hson[u],tp);
for(ll i=head[u];i;i=e[i].next){
ll v=e[i].to;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);
}
}
#define lson (o<<1)
#define rson (o<<1|1)
ll sumv[MAXN<<2],lzt[MAXN<<2];
void pushup(ll o){
sumv[o]=(sumv[lson]+sumv[rson])%MOD;
}
void pushdown(ll o,ll l,ll r){
if(lzt[o]){
ll mid=l+r>>1;
(sumv[lson]+=lzt[o]*(mid-l+1))%=MOD;
(sumv[rson]+=lzt[o]*(r-mid))%=MOD;
(lzt[lson]+=lzt[o])%=MOD;
(lzt[rson]+=lzt[o])%=MOD;
lzt[o]=0;
}
}
void build(ll o,ll l,ll r){
if(l==r){
sumv[o]=a[rl[l]];return;
}
ll mid=l+r>>1;
build(lson,l,mid);build(rson,mid+1,r);
pushup(o);
}
void change(ll o,ll l,ll r,ll ql,ll qr,ll val){
if(ql<=l&&qr>=r){(sumv[o]+=(r-l+1)*val)%=MOD;(lzt[o]+=val)%=MOD;return;}
ll mid=l+r>>1;
pushdown(o,l,r);
if(ql<=mid)change(lson,l,mid,ql,qr,val);
if(qr>mid)change(rson,mid+1,r,ql,qr,val);
pushup(o);
}
ll query(ll o,ll l,ll r,ll ql,ll qr){
if(ql<=l&&qr>=r){return sumv[o]%MOD;}
ll mid=l+r>>1,ans=0;
pushdown(o,l,r);
if(ql<=mid)(ans+=query(lson,l,mid,ql,qr))%=MOD;
if(qr>mid)(ans+=query(rson,mid+1,r,ql,qr))%=MOD;
return ans;
}
void chain_change(ll x,ll y,ll val){
ll tx=top[x],ty=top[y];
while(tx!=ty){
if(dep[tx]<dep[ty]){
change(1,1,n,id[ty],id[y],val);
y=fa[ty];
}
else {
change(1,1,n,id[tx],id[x],val);
x=fa[tx];
}
tx=top[x],ty=top[y];
}
if(dep[x]<dep[y])swap(x,y);
change(1,1,n,id[y],id[x],val);
}
ll chain_query(ll x,ll y){
ll tx=top[x],ty=top[y],ans=0;
while(tx!=ty){
if(dep[tx]<dep[ty]){
ans+=query(1,1,n,id[ty],id[y]);
ans%=MOD;
y=fa[ty];
}
else {
ans+=query(1,1,n,id[tx],id[x]);
ans%=MOD;
x=fa[tx];
}
tx=top[x],ty=top[y];
}
if(dep[x]<dep[y])swap(x,y);
ans+=query(1,1,n,id[y],id[x]);
return ans%MOD;
}