业余ACMer笔记·6月第4周补题

Gym - 101002C Greetings!

原题地址

代码:
参考博客
根据数据范围,不难想到状压DP,但一时没想起来该咋用,最近手感生疏了。

Gym101002E:K-Inversions

题目链接同上

代码:
参考博客
FFT板子题,唯一没想到的就是变换(我还是太菜了)

D .Programming Team

题目链接同上

代码:
参考博客
树上依赖背包,有点秀
在这里插入图片描述
代码来自参考博客

#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2610;
const double inf=1e20;
double dp[maxn][maxn],s[maxn],p[maxn],val[maxn];
int r[maxn],Laxt[maxn],Next[maxn],To[maxn];
int pos[maxn],tot,cnt,N,K,sz[maxn];
void add(int u,int v)
{
    Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
void dfs(int u)//求dfs序
{
    sz[u]=1; tot++; pos[tot]=u;
    for(int i=Laxt[u];i;i=Next[i]){
        dfs(To[i]); sz[u]+=sz[To[i]];//sz[u]是以u为根的子树大小
    }
}
bool check(double Mid)
{
    rep(i,1,N) val[i]=p[i]-s[i]*Mid;
    rep(i,1,tot+1) rep(j,1,K) dp[i][j]=-inf;//一定要弄到tot+1
    rep(i,0,tot+1) dp[i][0]=0;
    for(int i=tot;i>=1;i--)
    {
        int x=pos[i];
        for(int j=1;j<=K;j++)
        {
            dp[i][j]=max(dp[i+1][j-1]+val[x],dp[i+sz[x]][j]);//x选与不选
//这个转移方程也很有意思,学到如何二分求平均值了
        }
    }
    return dp[1][K]>=0;
}
int main()
{
    scanf("%d%d",&K,&N); K++;
    rep(i,1,N){
        scanf("%lf%lf%d",&s[i],&p[i],&r[i]);
        add(r[i],i);
    }
    dfs(0);
    double L=0,R=10000,Mid,ans=0; int T=30;
    while(T--){
        Mid=(L+R)/2;
        if(check(Mid)) ans=max(Mid,ans),L=Mid;
        else R=Mid;
    }
    printf("%.3lf\n",ans);
    return 0;
}

另外参考博客的J题,如果暴力模拟的话,因为路径总长有可能爆1e12,所以只能用set的lower_bound控制时间复杂度(一看到set.lower_bound就想起了在沈阳的惨剧)

K题我还没学会树分治,学完再补(不过感觉就算学会了,赛场上也打不出来)

Finding Lines

原题地址

代码:
参考博客
概率过题,真滴秀。。。
看另一篇博客,据说直接用randow会T,玄学。

random_shuffle

Gym101482题解
有空可以研究研究G和B

F. Independent Set

原题地址

代码:
懒得翻译了,注意要找的是边子集,且可以不联通就行了(自闭了好久)
参考博客

qw[v]表示以v为根节点的子树的方案数(包含一个点都不选这种非法情况)
初始化dp[i][2]=1我觉得也是考虑一个点都不选的情况

qw[v]=dp[v][1]+dp[v][0]-dp[v][2]
如果我们把dp[i][1]和dp[i][0]的表达式分别拆开,发现它们都包含qw[v1]qw[v2]…qw[vk]这一项,即dp[i]2,所以要去重。

D. Dreamoon Likes Sequences

原题地址

代码:
参考博客
有趣的组合数学问题,和上一题有点神似。
代码来自参考博客

#include
#define ll long long
#define ull unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define pb push_back
#define lowbit(x) (x&(-x))
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
void put1(){ puts("Yes") ;}void put2(){ puts("No") ;}void put3(){ puts("-1"); }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a =
(a*a)%p;b >>= 1;}return ans%p;}
const ull base=2333; const ull pp=19260811; const ull ppp=999998639;

const int manx=5e5+5;
const int mo=998244353;

ll dp[manx];

int main(){
    ll p=read();
    while(p--){
        ll d=read(),m=read();
        ll ans=1;
        for(int i=0;i<30;i++)
        {
            ll x= (1<<i) ;
            if(d < x) break;
            ans  = ans * (min((x<<1)-1ll,d) - x +1 +1) % m;
            //+1是这一位可能不被取的情况
        }
        ans = (ans -1 +m) %m;//减去的是一个都不取的情况
        printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(业余ACMer笔记·6月第4周补题)