template

2sat

#define Rev(x) ((x&1)?x+1:x-1)
namespace SAT2
{
    #define MX 400000
    vector<int> v[MX+5],V[MX+5];
    int n,b[MX+5],dn,q[MX+5],mark[MX+5],num,yes[MX+5];
    void init(int sz)
    {
        for(int i=1;i<=sz;++i) v[i].clear(),V[i].clear(),mark[i]=b[i]=yes[i]=0;
        dn=num=0;n=sz;
    }
    void ins(int f,int t)
    {
        v[f].push_back(t);
        v[Rev(t)].push_back(Rev(f));
        V[t].push_back(f);
        V[Rev(f)].push_back(Rev(t));
    }
    void dfs(int x)
    {
        b[x]=1;
        for(int i=0;i<v[x].size();++i)
            if(!b[v[x][i]]) dfs(v[x][i]);
        q[++dn]=x;
    }
    void rdfs(int x)
    {
        mark[x]=num;
        for(int i=0;i<V[x].size();++i)
            if(!mark[V[x][i]]) rdfs(V[x][i]);
    }
    bool Solve()
    {
        for(int i=1;i<=n;++i)
            if(!b[i]) dfs(i);
        for(int i=n;i;--i)
            if(!mark[q[i]]) ++num,rdfs(q[i]);
        for(int i=1;i<=n;++i) if(mark[i]==mark[Rev(i)]) return false;
        for(int i=1;i<=n;++i) yes[mark[i]>mark[Rev(i)]?i:Rev(i)]=1;
        return true;
    }
}

 SAM

namespace SAM
{
    #define MX 200000
    int n,cnt,last,c[MX+5][26],step[MX+5],fail[MX+5],v[MX+5],rk[MX+5];
    long long val[MX+5],sum[MX+5];
    void init(int len)
    {
        cnt=last=1;n=len;
        for(int i=1;i<=n<<1;++i)
            memset(c[i],0,sizeof(c[i])),step[i]=fail[i]=v[i]=val[i]=0;
    }
    void insert(int x)
    {
        int p=last,np=++cnt;step[np]=step[p]+1;val[np]=1;
        for(;p&&!c[p][x];p=fail[p]) c[p][x]=np;
        if(!p) fail[np]=1;
        else 
        {
            int q=c[p][x];
            if(step[q]==step[p]+1) fail[np]=q;
            else 
            {
                int nq=++cnt;step[nq]=step[p]+1;
                memcpy(c[nq],c[q],sizeof(c[q]));
                fail[nq]=fail[q];fail[np]=fail[q]=nq;
                for(;c[p][x]==q;p=fail[p]) c[p][x]=nq;
            }    
        }
        last=np;
    }
    void Build()
    {
        for(int i=1;i<=cnt;++i) ++v[step[i]];
        for(int i=1;i<=n;++i) v[i]+=v[i-1];
        for(int i=1;i<=cnt;++i) rk[v[step[i]]--]=i;
        for(int i=cnt;i;--i) val[fail[rk[i]]]+=val[rk[i]];val[1]=0;
        for(int i=cnt;i;sum[rk[i]]+=val[rk[i]],--i) for(int j=0;j<26;++j) if(c[rk[i]][j]) sum[rk[i]]+=sum[c[rk[i]][j]]; 
    }
    int Calc(char*s,int l,int r)
    {
        int x=1;
        for(int i=l;i<=r;++i)
            if(!c[x][s[i]-'a']) return 0;
            else x=c[x][s[i]-'a'];    
        return val[x];
    }
    #undef MX
}

TRIE trie 字典树

namespace TRIE
{
    #define MX 100000    
    int cnt,c[MX+5][26],val[MX+5];
    void init(int len)
    {
        cnt=1;++len;
        for(int i=1;i<=len;++i) val[i]=0,memset(c[i],0,sizeof(c[i]));     
    }
    void ins(char*s,int l,int r)
    {    
        int x=1;
        for(int i=l;i<=r;++i)
        {
            if(!c[x][s[i]-'a']) c[x][s[i]-'a']=++cnt;
            x=c[x][s[i]-'a'];    
        }
        ++val[x];
    }
    long long Calc(char*s,int l,int r)
    {
        long long res=0;int x=1;    
        for(int i=l;i<=r;++i) 
            if(!c[x][s[i]-'a']) return res;
            else res+=val[x=c[x][s[i]-'a']];
        return res;
    }
    #undef MX
}

 Dinic 最大流 FLOW

namespace FLOW
{
    #define S 0
    #define T 1501    
    #define MM 4000000
    #define INF 2000000000
    int d[T+5],q[T+5],head[T+5],c[T+5],cnt,top;
    struct edge{int to,next,w;}e[MM+5];
    void init(){cnt=1;memset(head,0,sizeof(head));}
    inline void ins(int f,int t,int w)
    {
        e[++cnt]=(edge){t,head[f],w};head[f]=cnt;    
        e[++cnt]=(edge){f,head[t],0};head[t]=cnt;
    }
    bool bfs()
    {
        memset(d,0,sizeof(d));int i,j;
        for(d[q[top=i=1]=S]=1;i<=top;++i)
            for(j=c[q[i]]=head[q[i]];j;j=e[j].next)
                if(e[j].w&&!d[e[j].to]) d[q[++top]=e[j].to]=d[q[i]]+1;
        return d[T];    
    }
    int dfs(int x,int f)
    {
        if(x==T) return f;int used=0;    
        for(int&i=c[x];i;i=e[i].next)
            if(e[i].w&&d[e[i].to]==d[x]+1)
            {
                int w=dfs(e[i].to,min(f-used,e[i].w));
                e[i].w-=w;e[i^1].w+=w;used+=w;
                if(used==f) return f;    
            }
        return d[x]=-1,used;
    }
    int dinic()
    {
        int ans=0;
        while(bfs()) ans+=dfs(S,INF);
        return ans;
    }
    #undef MM
    #undef INF
}

 SA 后缀数组 suffixarray

namespace SA
{
    int sa[2][MN+5],rk[2][MN+5],k,v[MN+5],p=1,q=0,*Sa,*Rk,f[MD+1][MN+5],Lg[MN+5];
    void GetH(char*s,int*sa,int*rk,int n)
    {
        for(int i=1,k=0;i<=n;f[0][rk[i++]-1]=k,k=max(k-1,0)) if(rk[i]>1)
            for(int j=sa[rk[i]-1];s[i+k]==s[j+k];++k);
    }
    void CalSa(int*sa,int*rk,int*SA,int*RK,int n)
    {
        for(int i=1;i<=n;++i) v[rk[sa[i]]]=i;
        for(int i=n;i;--i) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k;
        for(int i=n-k+1;i<=n;++i) SA[v[rk[i]]--]=i;
        for(int i=1;i<=n;++i) RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+k]!=rk[SA[i-1]+k]);
    }
    void Build(char*s,int n)
    {
        memset(f,63,sizeof(f));Lg[0]=-1;
        for(int i=1;i<=n;++i) ++v[s[i]-'a'];
        for(int i=1;i<26;++i) v[i]+=v[i-1];
        for(int i=1;i<=n;++i) sa[q][v[s[i]-'a']--]=i;
        for(int i=1;i<=n;++i) rk[q][sa[q][i]]=rk[q][sa[q][i-1]]+(s[sa[q][i]]!=s[sa[q][i-1]]);
        for(k=1;k<n;k<<=1,swap(p,q)) CalSa(sa[q],rk[q],sa[p],rk[p],n);
        GetH(s,sa[q],rk[q],n);Sa=sa[q];Rk=rk[q];
        for(int i=1;i<=n;++i) Lg[i]=Lg[i>>1]+1;
        for(int i=1;i<=MD;++i)for(int j=1;j<=n;++j)
            if(j+(1<<i)-1<=n) f[i][j]=min(f[i-1][j],f[i-1][j+(1<<i-1)]);
    }
    int Query(int l,int r)
    {
        int lg=Lg[r-l+1];
        return min(f[lg][l],f[lg][r-(1<<lg)+1]);    
    }
    pair<int,int> Inter(int x,int len,int n)
    {
        int l=1,r=x-1,mid,L=x,R=x;
        while(l<=r)
            if(Query(mid=(l+r>>1),x-1)>=len) L=mid,r=mid-1;
            else l=mid+1;
        l=x+1,r=n;
        while(l<=r)
            if(Query(x,(mid=(l+r>>1))-1)>=len) R=mid,l=mid+1;
            else r=mid-1;
        return make_pair(L,R);
    }
}

 klognlogk? Poly

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define MN 8200
#define MM 32767
#define mod 1000000007
const double pi=acos(-1);
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(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void R(int&x,int y){x+=y;x>=mod?x-=mod:0;}
int pow(int x,int k)
{
    int sum=1;
    for(;k;k>>=1,x=1LL*x*x%mod)
        if(k&1) sum=1LL*sum*x%mod;
    return sum; 
}    
namespace Poly 
{
    #define MX 512
    struct cp
    {
        double r,u;
        cp(double _r=0,double _u=0):r(_r),u(_u){}
        friend cp operator + (const cp&x,const cp&y){return cp(x.r+y.r,x.u+y.u);}
        friend cp operator - (const cp&x,const cp&y){return cp(x.r-y.r,x.u-y.u);}
        friend cp operator * (const cp&x,const cp&y){return cp(x.r*y.r-x.u*y.u,x.r*y.u+x.u*y.r);} 
        cp operator / (double y){return cp(r/y,u/y);}
    }w[10][2][MX+5],a[MX+5],b[MX+5],c[MX+5],d[MX+5],e[MX+5];int N,P,nl,Rev[MX+5],C[MX+5],D[MX+5],E[MX+5];
    inline long long R(double x){return (long long)(x+0.5)%mod;}
    void FFT(cp*x,int r)
    {
        for(int i=0,j=0;i<N;++i)
        {
            if(i>j) swap(x[i],x[j]);
            for(int k=N>>1;(j^=k)<k;k>>=1);
        }
        for(int i=2;i<=N;i<<=1)for(int j=0;j<N;j+=i)for(int k=0;k<i>>1;++k)
        {
            cp t=x[j+k+(i>>1)]*w[P][r][N/i*k];
            x[j+k+(i>>1)]=x[j+k]-t;
            x[j+k]=x[j+k]+t;
        }
        if(r)for(int i=0;i<N;++i)x[i]=x[i]/N;
    }
    void Reverse(int*x,int n){for(int i=0;i<n-1-i;++i)swap(x[i],x[n-1-i]);}
    void mul(int len,int*A,int*B)
    {
        for(N=1,P=0;N<len;N<<=1,++P);N<<=1;++P;
        memset(a,0,sizeof(cp)*(N+5));memset(b,0,sizeof(cp)*(N+5));
        memset(c,0,sizeof(cp)*(N+5));memset(d,0,sizeof(cp)*(N+5));
        for(int i=0;i<len;++i) a[i]=cp(A[i]&MM,0),b[i]=cp(B[i]&MM,0),c[i]=cp(A[i]>>15,0),d[i]=cp(B[i]>>15,0);
        FFT(a,0);FFT(b,0);FFT(c,0);FFT(d,0);
        for(int i=0;i<N;++i) e[i]=a[i]*d[i]+b[i]*c[i],a[i]=a[i]*b[i],c[i]=c[i]*d[i];
        FFT(a,1);FFT(c,1);FFT(e,1);
        for(int i=0;i<N;++i) A[i]=((1LL<<30)*R(c[i].r)%mod+R(a[i].r)+(1LL<<15)*R(e[i].r)%mod+mod)%mod;
    }
    void GetInv(int*A,int*B,int n)
    {
        /*
        B(x)-B'(x) = 0 mod n/2
        B^2 -2BB' + B'2^2 = 0 mod n
        B - 2B' + AB'^2 = 0
        B = 2B' - AB'^2 
        */
        if(n==1){B[0]=pow(A[0],mod-2);B[1]=0;return;}GetInv(A,B,n>>1);
        for(int i=0;i<n;++i) C[i]=A[i],D[i]=B[i];
        mul(n>>1,B,B);mul(n,C,B);
        for(int i=0;i<n;++i) B[i]=(2LL*D[i]-C[i]+mod)%mod,B[i+n]=0;
    }
    void Mul(int len,int*A,int*B,int*S)
    {
        mul(len,A,B);if(2*len-2<len) return;
        /*
        A=SB+R
        A(1/x) = S(1/x) * B(1/x) + R(1/x)
        x^2*len-2 * A(1/x) = x^2len-2 * S(1/x) * len B(1/x) + x^n * R(1/x)
        RA = RS*RB + x^n-m+1 RR
        A->2*len-2 B->len-1  len-2
        */    
        for(nl=1;nl<len;nl<<=1);
        for(int i=0;i<len;++i) E[i]=A[len*2-2-i];
        for(int i=len-1;i<=len*2;++i) E[i]=Rev[i]=0;
        mul(len-1,E,Rev);Reverse(E,len-1);
        E[len]=E[len-1]=0;mul(len+1,E,S);
        for(int i=0;i<len;++i) A[i]=(A[i]-E[i]+mod)%mod,A[i+len]=0;
    }
    void init()
    {
        for(int i=1,j=2;i<=9;++i,j<<=1)
            for(int k=0;k<=j;++k) w[i][0][k]=w[i][1][j-k]=cp(cos(2*k*pi/j),sin(2*k*pi/j));    
    }
}
int n,m,p[20],f[MN+5],c[MN+5],A[31][MN*2+5],B[MN*2+5],CC[MN*2+5],P[MN*2+5],G[MN*2+5];
long long ts;
int main()
{
    n=read();m=read();scanf("%lld",&ts);f[0]=1;int mx=0,nl=1;Poly::init();
    for(int i=1;i<=n;++i) p[i]=read();
    for(int i=1;i<=m;++i) mx=max(mx,c[i]=read());
    for(int i=1;i<=m;++i) (CC[mx-c[i]]+=mod-1)%=mod;++CC[mx];
    for(;nl<mx;nl<<=1);
    Poly::Reverse(CC,mx+1);
    Poly::GetInv(CC,Poly::Rev,nl); 
    Poly::Reverse(CC,mx+1);
    for(int i=1;i<=mx;++i)
        for(int j=1;j<=m;++j) if(i>=c[j]) R(f[i],f[i-c[j]]);
    if(mx==1) A[0][0]=mod-CC[0]; else A[0][1]=1;    
    for(int i=1;i<=30;++i) memcpy(A[i],A[i-1],sizeof(A[i])),Poly::Mul(mx,A[i],A[i],CC);
    for(int t=1;t<=n;++t)
    {
        memset(B,0,sizeof(B));B[0]=1;
        for(int k=p[t],j=0;k;++j,k>>=1) if(k&1) Poly::Mul(mx,B,A[j],CC);
        for(int i=0;i<mx;++i) R(P[i],B[i]);
    }
    int ans=0;memset(B,0,sizeof(B));B[0]=1;
    for(;ts;ts>>=1,Poly::Mul(mx,P,P,CC))if(ts&1)Poly::Mul(mx,B,P,CC);
    for(int i=0;i<mx;++i) R(ans,1LL*B[i]*f[i]%mod);
    printf("%d\n",(ans%mod+mod)%mod); 
    return 0;
}

 积性函数求和 杜教筛 洲阁筛

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
#define ms(x) memset(x,0,sizeof(x))
#define MN 5000000
#define GG 2000000000
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(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
bool b[MN+5];long long val[MN+5],V[MN+5];
int mu[MN+5],s[MN/5],num=0,last[MN+5],tms[MN+5];
namespace dls
{
#define Magic 2333333
    struct Map{int to,next,w;}e[10000005];
    int cnt,head[Magic+5];
    void ins(int x,int w){int j=x%Magic;e[++cnt]=(Map){x,head[j],w};head[j]=cnt;}
    int Query(int x)
    {
        int j=x%Magic;
        for(int i=head[j];i;i=e[i].next)
            if(e[i].to==x) return e[i].w;
        return GG;    
    }
    int Calc(int n)
    {
        if(n<=MN/2) return mu[n];
        int res=Query(n);if(res!=GG) return res;
        int sum=1;
        for(int i=2,last;i<=n;i=last+1)
        {
            last=n/(n/i);
            sum=sum-(last-i+1)*Calc(n/i);    
        }
        ins(n,sum);return sum;
    }
}
namespace zgg
{
#define MX 32000
    ll f[MX+5],F[MX+5],g[MX+5],G[MX+5];int l[MX+5],L[MX+5],c[MX+5],C[MX+5],sq,pnum,n;
    inline ll _F(int x,int i){return x<=sq?f[x]+4*max(0,c[x]-max(i+1,l[x])):F[n/x]+4*max(0,C[n/x]-max(i+1,L[n/x]));}
    inline ll _G(int x,int i){return x<=sq?g[x]-max(0,min(i,c[x])-l[x]):G[n/x]-max(0,min(i,C[n/x])-L[n/x]);}
    inline ll S(int x){return (x+1)*(x+1);}
    void CalcF()
    {
        //f[i][j] 1-j中由pi-ppnum构成的数的S之和
        for(int i=1;i<=sq;++i) f[i]=F[i]=1;
        for(int i=pnum;i;--i)
        {
            for(int j=1;j<=sq&&l[j]>i;++j)
            {
                ll now=j*s[i];
                for(int k=1;now<=n;now*=s[i],++k)
                    f[j]+=S(k)*_F(now,i);    
            }
            for(int j=sq;j&&L[j]>i;--j)
            {
                for(int now=j/s[i],k=1;now;now/=s[i],++k)
                    F[j]+=S(k)*(F[now]+4*max(0,C[now]-max(i+1,L[now])));
            }
        }
    }
    void CalcG()
    {
        //g[i][j] 1-j中与前i个质数互质的S之和
        for(int i=1;i<=sq;++i) g[i]=n/i,G[i]=i;
        for(int i=1;i<=pnum;++i)
        {
            for(int j=1;j<=sq&&i<l[j];++j) g[j]-=_G(j*s[i],i);
            for(int j=sq;j&&i<L[j];--j) G[j]-=G[j/s[i]]-max(0,min(i,C[j/s[i]])-L[j/s[i]]);
        }
        for(int i=1;i<=sq;++i) 
        {
            g[i]=(g[i]-max(0,min(c[i],pnum+1)-l[i])-1)<<2;
            G[i]=(G[i]-max(0,min(C[i],pnum+1)-L[i])-1)<<2;    
        }
    }
    void Solve(int N)
    {
        n=N;if(N<=MN) return;
        sq=int(sqrt(n));while((sq+1)*(sq+1)<=n) ++sq; 
        for(pnum=1;s[pnum]<=sq;++pnum);--pnum;
        
        int cntp=0,cntl=0;
        for(int i=1;i<=sq;C[i++]=cntp) while(cntp<=pnum&&s[cntp]<=i) ++cntp;
        for(int i=sq;i;c[i--]=cntp) while(cntp<=pnum&&s[cntp]<=n/i) ++cntp;
        for(int i=1;i<=sq;L[i++]=cntl) while(s[cntl]*s[cntl]<=i) ++cntl;
        for(int i=sq;i;l[i--]=cntl) while(s[cntl]*s[cntl]<=n/i) ++cntl;
        
        ms(f);ms(F);ms(g);ms(G);
        CalcF();CalcG();
    }
    ll Calc(int x)
    {
        if(n/x<=MN) return V[n/x];
        long long ans=_F(x,0);
        for(int i=1;i<=sq&&n/x/i>sq;++i) ans+=1LL*val[i]*_G(x*i,0);
        return ans;    
    }
}
int main()
{
    freopen("function.in","r",stdin);
    freopen("function.out","w",stdout); 
    mu[1]=val[1]=1;
    for(int i=2;i<=MN;++i)
    {
        if(!b[i]) s[++num]=i,mu[i]=-1,last[i]=i,val[i]=4,tms[i]=1;
        for(int j=1;s[j]*i<=MN;++j)
        {
            b[s[j]*i]=1;last[s[j]*i]=s[j];
            if(i%s[j]==0)
            {
                mu[s[j]*i]=0;
                int t=0,q=i,p=s[j];
                while(q%s[j]==0) q/=s[j],p*=s[j],++t;
                tms[s[j]*i]=t+1;val[s[j]*i]=q>1?val[q]*val[p]:(t+2)*(t+2);
                break;
            }
            else mu[s[j]*i]=-mu[i],val[s[j]*i]=val[s[j]]*val[i],tms[s[j]*i]=1;
        }
    }
    for(int i=1;i<=MN;++i) mu[i]+=mu[i-1],V[i]=V[i-1]+val[i];
    for(int T=read();T;--T)
    {
        int n=read();long long ans=0;zgg::Solve(n);
        for(int j=1,last;j<=n;j=last+1)
        {
            last=n/(n/j);
            ans+=1LL*(dls::Calc(last)-dls::Calc(j-1))*zgg::Calc(j);
        }
        cout<<ans<<endl;
    }
    return 0;
}

miller_rabin/pollard_rho

map<ll,int> mp;
inline ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
inline ll Abs(ll x){return x<0?-x:x;}
inline ll Ran(){return (ll)rand()<<30|rand();}
inline ll Mul(ll x,ll y,ll mod){return ((x*y-(ll)(((long double)x*y+0.5)/mod)*mod)%mod+mod)%mod;}
inline ll pow(ll x,ll k,ll mod)
{
    ll res=1;
    for(x%=mod;k;k>>=1,x=Mul(x,x,mod)) if(k&1) res=Mul(res,x,mod);
    return res;
}
bool Miller(ll n)
{
    if(n==2) return true;
    if(n==1||~n&1) return false;
    ll a=0,b=n-1;
    while(~b&1) ++a,b>>=1;
    for(int t=1;t<=MT*10;++t)
    {
        ll x=Ran()%(n-1)+1,y=pow(x,b,n);
        for(int j=0;j<a;++j,y=x)
            if((x=Mul(y,y,n))==1&&y!=1&&y!=n-1) return false;
        if(y!=1) return false;
    }
    return true;
}
ll Rho(ll n,ll c)
{
    ll k=2,x=Ran()%n,y=x,p=1;
    for(int i=1;p==1;++i)
    {
        y=(Mul(y,y,n)+c)%n;p=gcd(n,Abs(x-y));
        if(i==k) k<<=1,x=y;
    }
    return p;
}
void Solve(ll n)
{
    if(n==1) return;
    if(Miller(n)) 
    {
        if(mp[n]) ++c[mp[n]];
        else mp[n]=++num,p[num]=n,c[num]=1;
        return;
    }
    ll c=n;
    while(c>=n) c=Rho(n,Ran()%(n-1));
    Solve(c);Solve(n/c);
}

 bitset

#ifdef BITSET_COUNT
int numbit[1<<16];
#endif
struct Bitset
{
// Bitset Template by FallDream 2018.6.26
#define BITLEN 70000
#define ull unsigned long long
    ull s[BITLEN/64+1];int len;
    Bitset(){}
    void reset(int k=0){memset(s,k?255:0,sizeof(s));}
    void flip(int x){s[x>>6]^=1ULL<<(x&63);}
    void set(int x,int k=1){k?s[x>>6]|=1ULL<<(x&63):s[x>>6]&=-(1ULL<<(x&63))-1;}
    bool operator [](int x){return bool(s[x>>6]&(1ULL<<(x&63)));}
    bool any()
    {
        for(int i=0;i<=BITLEN/64;++i) if(s[i]) return true;
        return false;    
    }
    int count()
    {
#ifndef BITSET_COUNT 
    return 0;
#else
    int res=0;
    for(int i=0;i<=BITLEN/64;++i) 
        res+=numbit[s[i]&65535]+numbit[(s[i]>>16)&63555]
            +numbit[(s[i]>>32)&65535]+numbit[(s[i]>>48)&65535];
    return res;
#endif
    }
    int lowbit()
    {
        for(int i=0;i<=BITLEN/64;++i)if(s[i])
        {
            int l=0,r=63,mid,res;
            while(l<=r)
                if(s[i]>>(mid=l+r>>1)) res=mid,l=mid+1;
                else r=mid-1;
            return res+(i<<6);
        }
        return -1;
    }
    inline void Cut(){if((BITLEN&63)<63)s[BITLEN/64]&=(1ULL<<(BITLEN&63)+1)-1;}
    Bitset operator ~ (){
        Bitset c;c.reset();
        for(int i=0;i<=BITLEN/64;++i)c.s[i]=s[i]^(ull)-1;
        c.Cut();return c;
    }
    Bitset operator << (int len)
    {
        Bitset c;c.reset();int tlen=len>>6;len&=63;ull la=0;
        for(int i=tlen,j=0;i<=BITLEN/64;++i,++j)
            c.s[i]=(s[j]<<len)|la,la=len?s[j]>>(64-len):0;
        c.Cut();return c;
    }
    Bitset operator >> (int len)
    {
        Bitset c;c.reset();int tlen=len>>6;len&=63;ull la=0;
        for(int i=BITLEN/64-tlen,j=BITLEN/64;i>=0;--i,--j)
            c.s[i]=(s[j]>>len)|la,la=len?(s[j]&((1<<len)-1))<<(64-len):0;
        c.Cut();return c;
    }
    Bitset operator | (const Bitset&y)
    {
        Bitset c;
        for(int i=0;i<=BITLEN/64;++i) c.s[i]=s[i]|y.s[i];
        return c;
    }
    Bitset operator & (const Bitset&y)
    {
        Bitset c;
        for(int i=0;i<=BITLEN/64;++i) c.s[i]=s[i]&y.s[i];
        return c;    
    }
    void operator &= (const Bitset&y){(*this)=(*this)&y;}
    void operator |= (const Bitset&y){(*this)=(*this)|y;}
};
int main()
{
#ifdef BITSET_COUNT
    for(int i=1;i<1<<16;++i) numbit[i]=numbit[i>>1]+(i&1);
#endif
    return 0;
}

KM

namespace KM
{
    #define V 400
    #define INF 2000000000
    int n,m,N,d[V+5][V+5],matchx[V+5],matchy[V+5],mn[V+5],from[V+5],q[V+5],top,tail,lx[V+5],ly[V+5];
    bool visx[V+5],visy[V+5];
    void init(int _n=0,int _m=0)
    {
        n=_n;m=_m;memset(d,0,sizeof(d));
        memset(matchx,0,sizeof(matchx));memset(matchy,0,sizeof(matchy));
        memset(lx,0,sizeof(lx));memset(ly,0,sizeof(ly));
    }
    void ins(int x,int y,int w){d[x][y]=w;lx[x]=max(lx[x],w);}
    void Modlabel()
    {
        int d=INF;
        for(int i=1;i<=N;++i) if(!visy[i]) d=min(d,mn[i]);
        for(int i=1;i<=N;++i) if(visx[i]) lx[i]-=d;
        for(int i=1;i<=N;++i) if(visy[i]) ly[i]+=d; else mn[i]-=d;
    }
    int Find(int y)
    {
        memset(visy,0,sizeof(visy));memset(visx,0,sizeof(visx));
        for(int i=1;i<=N;++i) mn[i]=INF;
        q[tail=0,top=1]=y;
        for(;;)
        {
            while(tail<top)
            {
                int x=q[++tail];visx[x]=1;
                for(int j=1;j<=N;++j) if(!visy[j])
                {
                    int now=lx[x]+ly[j]-d[x][j];
                    if(now>mn[j]) continue;from[j]=x;
                    if(!now)
                    {
                        if(!matchy[j]) return j;
                        visy[j]=1;q[++top]=matchy[j];
                    }
                    else mn[j]=min(mn[j],now);
                }
            }
            Modlabel();
            for(int i=1;i<=N;++i) if(!visy[i]&&!mn[i])
            {
                if(!matchy[i]) return i;
                visy[i]=1;q[++top]=matchy[i];
            }
        }
    }
    long long Solve()
    {
        N=max(n,m);
        for(int i=1;i<=N;++i)
        {
            int y=Find(i);
            while(y) swap(y,matchx[matchy[y]=from[y]]);
        }
        long long ans=0;
        for(int i=1;i<=N;++i) ans+=lx[i]+ly[i];
        return ans;
    }
    #undef V
    #undef INF
}

 

posted @ 2017-09-24 00:25  FallDream  阅读(509)  评论(0编辑  收藏  举报