JSOI2015

A salsman

题面:Luogu
题解:树形dp
考虑设\(dp[u]\)表示经过\(u\)及其子树的最大收益
停留次数就把子树的收益算一下排个序取前多少个就好了
第二问的话不是独自的有几种情况

  • 这颗子树的选了的和没选的有收益相同的
  • 有选了收益0的(也就是可选可不选)
  • 子树里有不是独自的
    分类讨论一下即可

code

D 子集选取

题面:Luogu
题解:
由手玩小样例可以得到\(ans=2^{nk}\)
显然对每个数可以分开计算
对于一个数,每一步都可以选或者不选,走k步,把选了的全部丢到最前面即可,方案数为\(2^k\)
因为每个数都可以选或者不选,所以总方案数\(2^{nk}\)
code

G 非诚勿扰

题面:Luogu
题解:树状数组,概率
s个候选人中选了第x个的概率为
\begin{aligned}
ans &=p* [(1-p)^{x-1}+(1-p)^{s+x-1}+...] \newline
&=p* (1-p)^{x-1}* \frac{1-0}{1-(1-p)^s}
\end{aligned}
可以发现我们要求的东西是一个类似逆序对的东西,上树状数组搞一下即可
code

H 套娃

题面:Luogu
题解:贪心
把out扔到multiset里面,每个in与能放的最大的out匹配
证明可以看\(\text{M}\)\(\color{red}{\text{_sea}}\)博客
code

I 最小表示

题面:bzoj
题解:bitset 乱搞
考虑对于每条边\(u,v\)求出\(u\)能到的所有点和能到\(v\)的所有点,如果这两个有并集则这条边可以删掉
用拓扑排序求出能到某个点的所有点,再在反图上跑一遍即可
code

L 染色问题

题面:Luogu
题解:容斥
考虑\(i\)\(j\)列不涂,\(k\)种颜色不用,随意涂
则此时答案为
\[{n\choose i}{m\choose j}{c\choose k}(c-k+1)^{(n-i)*(m-j)}\]
其中\(c-k+1\)是因为还可以不涂
于是容斥一下
\[ans=\sum_{i=0}^{n}{\sum_{j=0}^{m}{\sum_{k=0}^{c}{(-1)^{i+j+k}{n\choose i}{m\choose j}{c\choose k}(c-k+1)^{(n-i)*(m-j)}}}}\]
code

M 最大公约数

题面:Luogu
题解:
有一个结论:序列的gcd个数是\(O(\log)\)
于是把r扫一遍,把所有gcd会改变的点扔到vector里面
不理解可以自己输出一下中间变量
code

A code

#include<bits/stdc++.h>
using namespace std;

inline void read(int& x)
{
    x=0;char c=getchar();int f=1;
    while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
    x*=f;
}
#define maxn 100005
int n,val[maxn],s[maxn],dp[maxn],f[maxn];
struct Edge
{
    int fr,to;
}eg[maxn<<1];
int head[maxn],edgenum;
inline void add(int fr,int to)
{
    eg[++edgenum]=(Edge){head[fr],to};
    head[fr]=edgenum;
}
inline bool cmp(const int& x,const int& y)
{
    return dp[x]>dp[y];
}
vector<int> ve;

void dfs(int rt,int fa)
{
    dp[rt]=val[rt];
    for(int i=head[rt];i;i=eg[i].fr)
        if(eg[i].to!=fa) dfs(eg[i].to,rt);
    ve.clear();
    for(int i=head[rt];i;i=eg[i].fr)
        if(eg[i].to!=fa&&dp[eg[i].to]>=0) ve.push_back(eg[i].to);
    sort(ve.begin(),ve.end(),cmp);
    int lim=min(s[rt]-1,(int)ve.size());
    for(int i=0;i<lim;++i) dp[rt]+=dp[ve[i]],f[rt]|=f[ve[i]];
    if(lim&&!dp[ve[lim-1]]) f[rt]=1;
    if(lim<(int)ve.size()&&dp[ve[lim-1]]==dp[ve[lim]]) f[rt]=1;
}
int main()
{
    read(n);s[1]=n;
    for(int i=2;i<=n;++i) read(val[i]);
    for(int i=2;i<=n;++i) read(s[i]);
    int x,y;
    for(int i=1;i<n;++i) read(x),read(y),add(x,y),add(y,x);
    dfs(1,0);
    printf("%d\n",dp[1]);
    puts(f[1]?"solution is not unique":"solution is unique");
    return 0;
}

top

D code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define p 1000000007
inline ll qpow(ll x,ll y)
{
    ll ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%p;
        x=x*x%p;
        y>>=1;
    }
    return ans;
}

int main()
{
    ll n,k;
    scanf("%lld%lld",&n,&k);
    printf("%lld\n",qpow(2,n*k%(p-1)));
    return 0;
}

top

G code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
    x=0;char c=getchar();int f=1;
    while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
    x*=f;
}
#define lb long double
#define maxn 500005
lb c[maxn],p;
int n,m;
inline int lowbit(const int& x)
{
    return x&(-x);
}
inline void update(const int& pos,const lb& val)
{
    for(int i=pos;i<=n;i+=lowbit(i)) c[i]+=val;
}
inline lb query(const int& pos)
{
    lb ans=0;
    for(int i=pos;i;i-=lowbit(i)) ans+=c[i];
    return ans;
}
vector<int> ve[maxn];
int main()
{
    read(n),read(m);
    scanf("%Lf",&p);
    int x,y;
    lb ans=0,tp;
    register vector<int>::iterator it;
    register int i;
    for(i=1;i<=m;++i) read(x),read(y),ve[x].push_back(y);
    for(i=1;i<=n;++i) sort(ve[i].begin(),ve[i].end());
    for(i=1;i<=n;++i)
    {
        if(ve[i].empty()) continue;
        tp=p/(1-pow(1-p,ve[i].size()));
        for(it=ve[i].begin();it!=ve[i].end();++it,tp*=(1-p))
            ans+=tp*(query(n)-query(*it)),update(*it,tp);
    }
    printf("%.2Lf\n",ans);
    return 0;
}

top

H code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
    x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 200005
int n;
struct Item
{
    int out,in,w;
    inline friend bool operator < (Item a,Item b)
        {
            return a.w>b.w;
        }
}it[maxn];
multiset<int> s;
multiset<int>::iterator tp;
int main()
{
    read(n);
    long long ans=0;
    for(int i=1;i<=n;++i)
        read(it[i].out),read(it[i].in),read(it[i].w),s.insert(it[i].out),ans+=1ll*it[i].w*it[i].in;
    sort(it+1,it+n+1);
    for(int i=1;i<=n;++i)
    {
        tp=s.lower_bound(it[i].in);
        if(tp!=s.begin()) ans-=1ll*(*--tp)*it[i].w,s.erase(tp);
    }
    printf("%lld\n",ans);
    return 0;
}

top

I code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
    x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 30005
int n,m,fr[maxn<<2],to[maxn<<2];
struct Graph
{
    struct Edge
    {
        int fr,to;
    }eg[maxn<<2];
    int deg[maxn],head[maxn],edgenum;
    bitset<maxn> bit[maxn];
    inline void add(int fr,int to)
        {
            eg[++edgenum]=(Edge){head[fr],to};
            head[fr]=edgenum;++deg[to];
        }
    void toposort()
        {
            queue<int> q;
            while(!q.empty()) q.pop();
            for(int i=1;i<=n;++i) if(!deg[i]) q.push(i);
            while(!q.empty())
            {
                int tp=q.front();q.pop();
                for(int i=head[tp];i;i=eg[i].fr)
                {
                    bit[eg[i].to]|=bit[tp],bit[eg[i].to][tp]=1;
                    if(!--deg[eg[i].to]) q.push(eg[i].to);
                }
            }
        }   
}G,G_rev;
int main()
{
    read(n),read(m);
    int ans=0;
    for(int i=1;i<=m;++i)
    {
        read(fr[i]),read(to[i]);
        G.add(fr[i],to[i]),G_rev.add(to[i],fr[i]);
    }
    G.toposort();G_rev.toposort();
    for(int i=1;i<=m;++i)
        if((G.bit[to[i]]&G_rev.bit[fr[i]]).any()) ++ans;
    printf("%d\n",ans);
    return 0;
}

top

L code

#include<bits/stdc++.h>
using namespace std;

inline void read(int& x)
{
    x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 405
#define p 1000000007
#define ll long long
int n,m,c,fac[maxn],inv[maxn],Pow[maxn*maxn];
inline int qpow(int x,int y)
{
    int ans=1;
    while(y)
    {
        if(y&1) ans=1ll*ans*x%p;
        x=1ll*x*x%p;
        y>>=1;
    }
    return ans;
}
inline int C(int n,int m)
{
    return 1ll*fac[n]*inv[m]%p*inv[n-m]%p;
}
int main()
{
    read(n),read(m),read(c);
    fac[0]=inv[0]=1;
    for(int i=1;i<=400;++i) fac[i]=1ll*fac[i-1]*i%p;
    inv[400]=qpow(fac[400],p-2);
    for(int i=399;i;--i) inv[i]=1ll*inv[i+1]*(i+1)%p;
    ll ans=0,tp;
    for(int k=0;k<=c;++k)
    {
        Pow[0]=1;
        for(int i=1;i<=n*m;++i) Pow[i]=1ll*Pow[i-1]*(c-k+1)%p;
        for(int i=0;i<=n;++i)
            for(int j=0;j<=m;++j)
            {
                tp=1ll*C(n,i)*C(m,j)%p*C(c,k)%p*Pow[(n-i)*(m-j)]%p;
                if((i+j+k)&1) ans-=tp;
                else ans+=tp;
            }
    }
    ans=(ans%p+p)%p;
    printf("%lld\n",ans);
    return 0;
}

top

M code

#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T& x)
{
    x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 100005
int n;
long long ans,a[maxn];
vector<int> ve,tp;
template<typename T>
T gcd(T a,T b)
{
    if(!b) return a;
    return gcd(b,a%b);
}
int main()
{
    read(n);
    for(int i=1;i<=n;++i) read(a[i]),ans=max(ans,a[i]);
    ve.push_back(1);
    for(int i=2;i<=n;++i)
    {
        tp.clear();tp.push_back(1);
        for(unsigned j=0;j<ve.size();++j)
        {
            #define tmp ve[j]
            a[tmp]=gcd(a[tmp],a[i]);
            ans=max(ans,(i-tmp+1)*a[tmp]);
            if(!j||a[tmp]!=a[ve[j-1]]) tp.push_back(tmp);
        }
        ve=tp;
        if(a[ve.back()]!=a[i]) ve.push_back(i);
    }
    printf("%lld\n",ans);
    return 0;
}

top

猜你喜欢

转载自www.cnblogs.com/123789456ye/p/12301479.html
今日推荐