BZOJ 4002~4007 JLOI2015 代码

题解戳这里

4002 有意义的字符串:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define P 7528443412579576937ull
using namespace std;
typedef unsigned long long ull;
ull b,d,n;
ull Times(ull x,ull y)
{
    ull re=0;
    while(y)
    {
        if(y&1)
        {
            re+=x;
            if(re>=P)
                re-=P;
        }
        x+=x;
        if(x>=P)
            x-=P;
        y>>=1;
    }
    return re;
}
namespace Matrix_Multiplication{
    struct Matrix{
        ull a[2][2];
        ull* operator [] (int x)
        {
            return a[x];
        }
        friend Matrix& operator *= (Matrix &x,Matrix y)
        {
            int i,j,k;
            Matrix z;
            memset(&z,0,sizeof z);
            for(i=0;i<2;i++)
                for(j=0;j<2;j++)
                    for(k=0;k<2;k++)
                        (z[i][j]+=Times(x[i][k],y[k][j]))%=P;
            return x=z;
        }
    }a;
    //a[i]=b*a[i-1]+(d-b*b)/4*a[i-2]
    //a[0]=2,a[1]=b
    Matrix Quick_Power(Matrix x,ull y)
    {
        Matrix re;
        re[0][0]=re[1][1]=1;
        re[1][0]=re[0][1]=0;
        while(y)
        {
            if(y&1) re*=x;
            x*=x; y>>=1;
        }
        return re;
    }
}
int main()
{
    using namespace Matrix_Multiplication;
    cin>>b>>d>>n;
    a[0][0]=0;
    a[1][0]=1;
    a[0][1]=d-b*b>>2;
    a[1][1]=b;
    Matrix ans=Quick_Power(a,n);
    cout<<(Times(ans[0][0],2)+Times(ans[1][0],b)-(d!=b*b&&~n&1))%P<<endl;
    return 0;
}

4003 城池攻占:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 300300
using namespace std;
struct Heap{

    #define HEIGHT(p) ((p)?(p)->height:0)

    Heap *ls,*rs;
    long long height,val,belong;
    long long times_mark,add_mark;
    void* operator new(size_t,long long _,long long __)
    {
        static Heap mempool[M],*C=mempool;
        C->ls=C->rs=0x0;
        C->height=1;
        C->val=_;
        C->belong=__;
        C->times_mark=1;
        C->add_mark=0;
        return C++;
    }
    void Times(long long x)
    {
        val*=x;
        times_mark*=x;
        add_mark*=x;
    }
    void Add(long long x)

    {
        val+=x;
        add_mark+=x;
    }
    void Push_Down()
    {
        if(times_mark!=1)
        {
            if(ls) ls->Times(times_mark);
            if(rs) rs->Times(times_mark);
            times_mark=1;
        }
        if(add_mark!=0)
        {
            if(ls) ls->Add(add_mark);
            if(rs) rs->Add(add_mark);
            add_mark=0;
        }
    }
    void Push_Up()
    {
        height=HEIGHT(rs)+1;
    }
    friend Heap* Merge(Heap *x,Heap *y)
    {
        if(!x) return y;
        if(!y) return x;
        if(x->val>y->val)
            swap(x,y);
        x->Push_Down();
        x->rs=Merge(x->rs,y);
        if( HEIGHT(x->rs)>HEIGHT(x->ls) )
            swap(x->ls,x->rs);
        x->Push_Up();
        return x;
    }
}*heap[M];
struct abcd{
    int to,next;
}table[M];
int head[M],tot;
int n,m;
int fa[M],dpt[M],ans[M];
long long h[M],a[M],v[M];
int st[M],ed[M];
void Add(int x,int y)
{
    table[++tot].to=y;
    table[tot].next=head[x];
    head[x]=tot;
}
void Tree_DP()
{
    static int q[M],r,h;
    int i,j;
    q[++r]=1;
    while(r!=h)
    {
        int x=q[++h];
        dpt[x]=dpt[fa[x]]+1;
        for(i=head[x];i;i=table[i].next)
            q[++r]=table[i].to;
    }
    for(j=n;j;j--)
    {
        int x=q[j];
        for(i=head[x];i;i=table[i].next)
            heap[x]=Merge(heap[x],heap[table[i].to]);
        while( heap[x] && heap[x]->val< ::h[x] )
        {
            ed[heap[x]->belong]=x;
            ans[x]++;
            heap[x]->Push_Down();
            heap[x]=Merge(heap[x]->ls,heap[x]->rs);
        }
        if(heap[x])
        {
            if(a[x]==0)
                heap[x]->Add(v[x]);
            else
                heap[x]->Times(v[x]);
        }
    }

}
int main()
{
    int i;long long x,y;
    cin>>n>>m;
    for(i=1;i<=n;i++)
        scanf("%lld",&h[i]);
    for(i=2;i<=n;i++)
    {
        scanf("%d%lld%lld",&fa[i],&a[i],&v[i]);
        Add(fa[i],i);
    }
    for(i=1;i<=m;i++)
    {
        scanf("%lld%lld",&x,&y);
        Heap *temp=new (x,i)Heap;
        st[i]=y;heap[y]=Merge(temp,heap[y]);
    }
    Tree_DP();
    for(i=1;i<=n;i++)
        printf("%d\n",ans[i]);
    for(i=1;i<=m;i++)
        printf("%d\n",dpt[st[i]]-dpt[ed[i]]);
    return 0;
}

4004 装备购买:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 550
#define MOD 999911659
using namespace std;
int n,m,cnt;
long long ans;
long long Quick_Power(long long x,long long y)
{
    long long re=1;
    while(y)
    {
        if(y&1) (re*=x)%=MOD;
        (x*=x)%=MOD; y>>=1;
    }
    return re;
}
struct Vector{
    long long a[M];
    friend istream& operator >> (istream &_,Vector &v)
    {
        int i;
        for(i=1;i<=m;i++)
            scanf("%I64d",&v.a[i]);
        return _;
    }
    void Elimination(const Vector &v,int pos)
    {
        int i;
        long long temp=(MOD-a[pos]*Quick_Power(v.a[pos],MOD-2)%MOD)%MOD;
        for(i=pos;i<=m;i++)
            (a[i]+=temp*v.a[i])%=MOD;
    }
    bool operator < (const Vector &v) const
    {
        return false;
    }
}*linear_bases[M];
pair<int,Vector> a[M];
bool Insert(Vector &v)
{
    int i;
    for(i=1;i<=m;i++)
        if(v.a[i])
        {
            if(!linear_bases[i])
            {
                linear_bases[i]=&v;
                return true;
            }
            v.Elimination(*linear_bases[i],i);
        }
    return false;
}
int main()
{
    int i;
    cin>>n>>m;
    for(i=1;i<=n;i++)
        cin>>a[i].second;
    for(i=1;i<=n;i++)
        scanf("%d",&a[i].first);
    sort(a+1,a+n+1);
    for(i=1;i<=n;i++)
        if(Insert(a[i].second))
            ++cnt,ans+=a[i].first;
    cout<<cnt<<‘ ‘<<ans<<endl;
    return 0;
}

4005 骗我呢:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 3003003
#define MOD 1000000007
using namespace std;
int n,m;
long long fac[M],inv[M],ans;
void Linear_Shaker()
{
    int i;
    for(fac[0]=1,i=1;i<=3000000;i++)
        fac[i]=fac[i-1]*i%MOD;
    for(inv[1]=1,i=2;i<=3000000;i++)
        inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD;
    for(inv[0]=1,i=1;i<=3000000;i++)
        (inv[i]*=inv[i-1])%=MOD;
}
long long C(int n,int m)
{
    if(n<m) return 0;
    return fac[n] * inv[m] % MOD * inv[n-m] % MOD ;
}
long long Calculate(int x,int y)
{
    if(x<0||y<0)
        return 0;
    return C(x+y,x);
}
void Flip1(int &x,int &y)//沿着直线y=x+1翻转
{
    swap(x,y);
    x--;y++;
}
void Flip2(int &x,int &y)//沿着直线y=x-(m+2)翻转
{
    swap(x,y);
    x+=m+2;y-=m+2;
}
int main()
{

    cin>>n>>m;
    Linear_Shaker();

    ans=Calculate(m+n+1,n);

    int x=m+n+1,y=n;
    while(x>=0&&y>=0)
    {
        Flip1(x,y);
        ans-=Calculate(x,y);
        Flip2(x,y);
        ans+=Calculate(x,y);
        ans%=MOD;
    }

    x=m+n+1,y=n;
    while(x>=0&&y>=0)
    {
        Flip2(x,y);
        ans-=Calculate(x,y);
        Flip1(x,y);
        ans+=Calculate(x,y);
        ans%=MOD;
    }

    cout<<(ans+MOD)%MOD<<endl;
    return 0;
}

4006 管道连接:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1010
using namespace std;
struct Key_Point{
    int color,point;
    bool operator < (const Key_Point &k) const
    {
        return color < k.color ;
    }
}points[20],_points[20];
struct abcd{
    int to,f,next;
}table[3030<<1];
int head[M],tot;
int n,m,p,c,cnt;
int f[1024][M],g[32];
int q[65540];
unsigned short r,h;
void Add(int x,int y,int z)
{
    table[++tot].to=y;
    table[tot].f=z;
    table[tot].next=head[x];
    head[x]=tot;
}
void SPFA(int f[])
{
    static bool v[M];
    int i;
    while(r!=h)
    {
        int x=q[++h];v[x]=false;
        for(i=head[x];i;i=table[i].next)
            if(f[table[i].to]>f[x]+table[i].f)
            {
                f[table[i].to]=f[x]+table[i].f;
                if(!v[table[i].to])
                    v[table[i].to]=true,q[++r]=table[i].to;
            }
    }
}
int Steiner_Tree()
{
    int i,j,k;
    for(i=1;i<1<<cnt;i++)
    {
        for(j=1;j<=n;j++)
        {
            for(k=i&(i-1);k;(--k)&=i)
                f[i][j]=min(f[i][j],f[k][j]+f[i^k][j]);
            if(f[i][j]!=0x3f3f3f3f)
                q[++r]=j;
        }
        SPFA(f[i]);
    }
    int ans=0x3f3f3f3f;
    for(i=1;i<=n;i++)
        ans=min(ans,f[(1<<cnt)-1][i]);
    return ans;
}
int main()
{
    int i,j,x,y,z;
    cin>>n>>m>>p;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        Add(x,y,z);Add(y,x,z);
    }
    for(i=1;i<=p;i++)
        scanf("%d%d",&points[i].color,&points[i].point);
    sort(points+1,points+p+1);
    p=0;
    for(i=1;points[i].color;i++)
        if(points[i].color==points[i-1].color||points[i].color==points[i+1].color)
            _points[++p]=points[i];
    memcpy(points,_points,sizeof points);
    for(i=1;i<=p;i++)
    {
        if(i==1||_points[i].color!=_points[i-1].color)
            ++c;
        points[i].color=c;
    }
    memset(g,0x3f,sizeof g);
    for(i=1;i<1<<c;i++)
    {
        cnt=0;
        for(j=1;j<=p;j++)
            if(i&(1<<points[j].color-1))
                ++cnt;
        memset(f,0x3f,sizeof(f[0][0])*M*(1<<cnt));
        cnt=0;
        for(j=1;j<=p;j++)
            if(i&(1<<points[j].color-1))
                f[1<<cnt++][points[j].point]=0;
        g[i]=Steiner_Tree();
    }
    for(i=1;i<1<<c;i++)
        for(j=i&(i-1);j;(--j)&=i)
            g[i]=min(g[i],g[j]+g[i^j]);
    cout<<g[(1<<c)-1]<<endl;
    return 0;
}

4007 战争调度:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1100
using namespace std;
int n,m;
int a[M][M],b[M][M],f[M][M];
//f[i][j]表示以i为根的子树中选择j个参战的最大收益
bool status[M];
void DFS(int x,int size)
{
    int i,j;
    if(x>=1<<n-1)
    {
        f[x][0]=f[x][1]=0;
        for(i=x>>1;i;i>>=1)
            if(status[i]==0)
                f[x][1]+=a[x][i];
            else
                f[x][0]+=b[x][i];
        return ;
    }
    status[x]=false;
    DFS(x<<1,size>>1);DFS(x<<1|1,size>>1);
    int limit=min(size,m);//x所在的子树中最多有limit个平民参战
    memset(f[x],0,sizeof(f[0][0])*(limit+1));
    for(i=0;i<=limit;i++)
    {
        int upper=min(size>>1,i);//左子树最多有upper个平民参战
        int lower=max(i-(size>>1),0);//左子树最少有lower个平民参战
        for(j=lower;j<=upper;j++)
            f[x][i]=max(f[x][i],f[x<<1][j]+f[x<<1|1][i-j]);
    }
    status[x]=true;
    DFS(x<<1,size>>1);DFS(x<<1|1,size>>1);
    for(i=0;i<=limit;i++)
    {
        int upper=min(size>>1,i);//左子树最多有upper个平民参战
        int lower=max(i-(size>>1),0);//左子树最少有lower个平民参战
        for(j=lower;j<=upper;j++)
            f[x][i]=max(f[x][i],f[x<<1][j]+f[x<<1|1][i-j]);
    }
}
int main()
{
    int i,j;
    cin>>n>>m;
    for(i=1<<n-1;i<1<<n;i++)
        for(j=i>>1;j;j>>=1)
            scanf("%d",&a[i][j]);
    for(i=1<<n-1;i<1<<n;i++)
        for(j=i>>1;j;j>>=1)
            scanf("%d",&b[i][j]);
    DFS(1,1<<n-1);
    int ans=0;
    for(i=0;i<=m;i++)
        ans=max(ans,f[1][i]);
    cout<<ans<<endl;
}
时间: 2024-11-01 16:23:27

BZOJ 4002~4007 JLOI2015 代码的相关文章

bzoj 4002: [JLOI2015]有意义的字符串

这个题... 1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #define REP(i, a, b) for (int i = a; i < b; i++) 5 #define mp make_pair 6 #define pb push_back 7 #d

BZOJ 1974: [Sdoi2010]auction 代码拍卖会( dp )

在1, 11, 111……中选<=8个, + 11..(n个1)拼出所有可能...这些数mod p至多有p中可能, 找出循环的处理一下. 那么dp就很显然了...dp(i, j, k)表示前i种选出了j个, 组合出的数mod p = k, 然后递推一下就好了. ----------------------------------------------------------------------- #include<cstdio> #include<cstring> #i

【BZOJ 4003】 [JLOI2015]城池攻占

4003: [JLOI2015]城池攻占 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 206 Solved: 89 [Submit][Status][Discuss] Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, 其中 fi 小于i.也就是说,所有城池构成了一棵有根树.这 m 个骑士用 1

BZOJ 4003 【JLOI2015】城池攻占

Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, 其中 fi <i.也就是说,所有城池构成了一棵有根树.这 m 个骑士用 1 到 m 的整数表示,其 中第 i 个骑士的初始战斗力为 si,第一个攻击的城池为 ci. 每个城池有一个防御值 hi,如果一个骑士的战斗力大于等于城池的生命值,那么骑士就可 以占领这座城池:否则占领失败,骑士将在这座城池牺

BZOJ 4002 有意义的字符串

WA一下午的原因是矩阵有两个值打反了... #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define ll unsigned long long #define mod 7528443412579576937UL using namespace std; struct matrix { ll a[3][3];

BZOJ 3143 HNOI2013 游走 高斯消元 期望

这道题是我第一次使用高斯消元解决期望类的问题,首发A了,感觉爽爽的.... 中文题目,就不翻大意了,直接给原题: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. 输出最小的总分期望值. Solution: 这题贪心很明显

2016.6.10 考试总结

汽艇(Boat.cpp/c/pas) [问题描述] 有 n 个人要去坐 1 汽艇,每个人单独坐汽艇的快乐程度是 Ci,每多一个人,他的快乐程度会减去 Di,请求出使快乐程度之和达到最大的方案.(假设汽艇的容量足够大). [输入格式] 输入文件共有 3 行: 第1 行是一个整数 n: 第2 行有n 个整数,依次表示每个人单独坐汽艇的快乐程度 Ci(1<=Ci<=10000): 第3 行有n 个整数,依次表示每多 1 人,每个人快乐程度的下降值 Di(1<=Di<=10). [输出格式

Hexo快速搭建静态博客并实现远程VPS自动部署

这篇文章将如何搭建hexo,以及如何通过git webhooks实现远程vps的自动部署 这篇文件适合的条件: 简单的用于个人博客.公司博客展示,hexo的定位是静态博客,要实现动态服务器的功能并不适合 有自己私有的服务器.vps.域名 git仓库,Github或国内的Coding.net hexo本地部署 流程:先在本机搭建好hexo环境,push到git仓库,再部署到服务器上. 第一步,安装hexo命令行工具,这个工具在服务器端也需要执行安装 1 npm install hexo-cli -

BZOJ2773

传送门:BZOJ2773 以y为key建树,维护最大值,树上二分即可. 吐槽一下学校评测机,我艹我在bzoj上AC的代码T完了. 代码上的小细节见下. #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <algorithm> #include <iostream> #include <set> #include