各种模板

一些奇妙的模板。慢慢更新好啦。

目录之外的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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值