首页 > 其他分享 >CSP 模拟 5

CSP 模拟 5

时间:2023-07-27 19:01:03浏览次数:39  
标签:tx int mid dep 模拟 CSP qwq define

T1 第一题

贪心,观察肯定是从较浅的点上来一个士兵或者从根节点来一个士兵,用 set 或者 vector 启发式合并维护这个过程即可

点击查看代码
#include<bits/stdc++.h>
#define N 100005
#define inf 0x3f3f3f3f
#define pii pair<int,int>
#define mp make_pair
using namespace std;

int n,head[N],tot,dep[N],mdep[N],ans;
vector<int> qwq[N];
struct edge{
    int v,nxt;
}e[N*2];
inline void add(int u,int v){
    e[++tot].v=v;
    e[tot].nxt=head[u];
    head[u]=tot;
}
void dfs(int u,int fa){
    dep[u]=dep[fa]+1;mdep[u]=dep[u];
    bool tmp=1;
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,u);tmp=0;
        mdep[u]=max(mdep[u],mdep[v]);
        for(int j:qwq[v]) qwq[u].push_back(j);
    }
    if(tmp){
        qwq[u].push_back(dep[u]);
        ans+=dep[u];return;
    }
    sort(qwq[u].begin(),qwq[u].end(),greater<int>());
    int cnt=0;
    for(int i=qwq[u].size()-1;i>=1;i--){
        if(qwq[u][i]-dep[u]*2>=0) break;
        ans+=qwq[u][i]-dep[u]*2;cnt++;
    }
    while((cnt--)&&qwq[u].size()) qwq[u].pop_back();
}

int main(){
    cin>>n;
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    dep[0]=-1;dfs(1,0);
    printf("%d",ans);
}

T2 第二题

这个答案具有单调性显然,考虑决定答案瓶颈的数即可

二分答案,每次用类似 spfa 的方式,首先把所有数都压进一个队列中,每次将队首的数和周围的 6 个数的差值补到 \(mid\),如果一个节点被更新则压入队列继续更新,直到队列为空,然后比较操作次数和 \(k\) 的大小即可

点击查看代码
#include<bits/stdc++.h>
#define N 100005
#define pii pair<int,int>
#define mp make_pair
#define int long long
#define inf 0x3f3f3f3f
using namespace std;

int r,c,k,maxn,minn=inf,sum,vis[N];
int mvx[6]={0,0,-1,-1,1,1},mxy[6]={-1,1,0,1,-1,0};
vector<int> a[N],b[N];
inline int id(int x,int y){return c*(x-1)+y;}
bool check(int mid){
    queue<pii> q;
    memset(vis,1,sizeof(vis));
    for(int i=1;i<=r;i++){
        b[i]=a[i];
        for(int j=1;j<=c;j++)
            q.push(mp(i,j));
    }
    int tmp=0;
    while(!q.empty()){
        int x=q.front().first,y=q.front().second;
        q.pop();vis[id(x,y)]=false;
        int Maxn=0;
        for(int i=0;i<6;i++){
            int tx=x+mvx[i],ty=y+mxy[i];
            if(tx<1||tx>r||ty<1||ty>c) continue;
            Maxn=max(Maxn,b[tx][ty]);
        }
        if(Maxn-b[x][y]>mid){
            tmp+=Maxn-b[x][y]-mid;
            b[x][y]=Maxn-mid;
        }
        for(int i=0;i<6;i++){
            int tx=x+mvx[i],ty=y+mxy[i];
            if(tx<1||tx>r||ty<1||ty>c) continue;
            if(abs(b[x][y]-b[tx][ty])>mid){
                tmp+=b[x][y]-b[tx][ty]-mid;
                b[tx][ty]=b[x][y]-mid;
                if(!vis[id(tx,ty)]){
                    q.push(mp(tx,ty));
                    vis[id(tx,ty)]=true;
                }
            }
        }
        if(tmp>k) return false;
    }
    return true;
}

signed main(){
    // srand(time(0)^*(new unsigned int));
    cin>>r>>c>>k;
    for(int i=1;i<=r;i++){
        a[i].push_back(0);
        for(int j=1;j<=c;j++){
            int x;scanf("%lld",&x);
            maxn=max(maxn,x);minn=min(minn,x);
            a[i].push_back(x);
        }
    }
    int l=0,r=maxn-minn,ans=maxn-minn;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) r=mid-1,ans=mid;
        else l=mid+1;
    }
    printf("%lld\n",ans);
}

T3 第三题

数位 dp,通常的数位 dp 为考虑是否压住上界,这个是考虑是否压住上下界

设状态 \(f_{i,j,0/1,0/1}\) 为选到第 \(i\) 位,选了 \(j\) 个 0,是否压住上下界,统计 \(a-1\sim \infty\) 和 \(b\sim \infty\) 的方案数相减即可

点击查看代码
代码

第四题

将 \(k^2\) 拆成 \(2\binom k2 +k\),就变为统计值都为 \(x\) 的点对数乘 2 和值为 \(x\) 的点数

设 \(f_{i,j}\) 为选到第 \(i\) 个位置,最大值为 \(j\) 的方案数,\(g_{i,j}\) 为从 \(i\) 位置,最大值为 \(j\) 的情况下选到末尾的方案数

则 \(i\) 位置对 \(x\) 的贡献为:

\[\sum_{y\ge x} f_{i-1,y}(g_{i+1,j}+2(n-i)g_{i+2,j})\\+f_{i-1,x-1}(g_{i+1,x}+2(n-i)g_{i+2,x}) \]

即为将 \(x\) 填到 \(i\) 位置,再考虑将前边和后边合起来,考虑对后边出现次数和点对的影响

点击查看代码
#include<bits/stdc++.h>
#define N 3005
#define int long long
using namespace std;

int n,m,ans[N];
int f[N][N],g[N][N],sum[N][N];

signed main(){
    cin>>n>>m;
    f[0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            f[i][j]=(f[i-1][j]*j+f[i-1][j-1])%m;
    for(int i=1;i<=n;i++) g[n+1][i]=1;
    for(int i=n;i>=1;i--)
        for(int j=n;j>=1;j--)
            g[i][j]=(g[i+1][j]*j+g[i+1][j+1])%m;
    for(int i=1;i<=n;i++)
        for(int j=n;j>=1;j--)
            sum[i][j]=(sum[i][j+1]+f[i-1][j]*(g[i+1][j]+2*(n-i)%m*g[i+2][j]%m))%m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            ans[j]=(ans[j]+sum[i][j]+f[i-1][j-1]*(g[i+1][j]+2*(n-i)%m*g[i+2][j]%m)%m)%m;
    for(int i=1;i<=n;i++)
        printf("%lld ",ans[i]);
}

标签:tx,int,mid,dep,模拟,CSP,qwq,define
From: https://www.cnblogs.com/Rolling-star/p/17585794.html

相关文章

  • set.a.light 3D STUDIO - 3D摄影棚模拟布光软件mac/win版
    set.a.light3DSTUDIO是一款专业的摄影灯光模拟软件,为摄影师和摄影爱好者提供了一个真实、细致的虚拟摄影棚环境。它可以帮助用户在计算机上进行灯光设置和调整,以达到理想的照片效果。→→↓↓载set.a.light3DSTUDIO set.a.light3DSTUDIO具有丰富的功能和直观的界面,使用......
  • 第一次模拟赛总结
    第一次摸底考试总结考试结果成绩:\(100+100+80+0+70+0=350\)排名:#\(18\)逐题分析C钱到题出现の问题约瑟夫环使用了数组进行维护,取模麻烦,使用std::queue更为方便坑点队列q需要进行初始化正确代码#include<bits/stdc++.h>usingnamespacestd;intmain(){......
  • 2023 暑假集训模拟赛 Day 3
    比赛题目共\(2\)套,其中初赛题\(1\)套,复赛\(2\)题。比赛时间:\(10:50-12:00a.m\)。Part0x01过程-Process\(8:30\,a.m.\)做初赛题目;\(10:40\,a.m.\)拿到题目;\(10:41\,a.m.\)先写\(\text{T1}\),发现有点像分类讨论;\(10:50\,a.m.\)发现\(\text{T1}\)不需要那......
  • CSP6
    T1题目描述给出一个长为的排列,请你把它排序。排序方法是:定义一种操作表示交换,先找到所有逆序对满足,任意排成一个排列,使得按照这个顺序操作以后是单调递增的。如果有多种排列,输出任意一种。输入格式第一行输入,第二行输入数组。保证是排列。输出格式如果不存在答案,输出。否则......
  • 【垫底模拟】CSP模拟-6
    新系列,系列名叫垫底模拟,厉害吧T1排序最开始想的都是很简单的东西,就是把最大的数放到最后嘛,然后发现显然不行,比如说:hack:input:515324output:34252423题目很明显地告诉我们先输出逆序对数\(m\)再输出交换\(m\)行操作,这\(m\)次操作还必须针对我们求......
  • 视频直播系统源码,vue自定义模拟滚动条
    视频直播系统源码,vue自定义模拟滚动条vscroll自定义滚动条模板 <template> <divclass="vui__scrollbar"ref="ref__box"@mouseenter="handleMouseEnter"@mouseleave="handleMouseLeave"v-resize="handleResize">  <div:......
  • 2023 暑假集训模拟赛 Day 2
    比赛题目共2套,其中初赛题1套,复赛2题。比赛时间:\(10:50-12:00a.m\)Part0x01过程-Process\(8:40\,a.m.\)做初赛题目;\(10:40\,a.m.\)拿到题目;\(10:51\,a.m.\)先写\(\text{T2}\),发现是初赛考过的题目,但时限变小;\(11:20\,a.m.\)在\(\text{T2}\)上花了太久,没调出来,......
  • 蒙特卡洛模拟
    MonteCarloSimulationIntroduction蒙特卡洛是西欧小国摩纳哥最著名的一区,以豪华的赌场闻名于世。(赌场,意味着大量重复的随机过程)蒙特卡洛模拟是一种,通过大量随机采样,预测不确定事件可能结果的的数学技术。这个想法的数学保证是大数定律(Lawoflargenumbers):样本数量越多,则其算......
  • 3.1 模拟 参考代码
    P2670[NOIP2015普及组]扫雷游戏#include<cstdio>charmine[105][105];intdx[8]={-1,-1,-1,0,0,1,1,1};intdy[8]={-1,0,1,-1,1,-1,0,1};intmain(){intn,m;scanf("%d%d",&n,&m);for(inti=0;i<n;......
  • GDI+区域(Region)排除与路径(GraphicsPath)叠加透明
    1、区域(Region)排除 1CRectrt;2GetClientRect(&rt);34GraphicsPathpa;5pa.AddEllipse(0,0,rt.Width(),rt.Height());6Regionrg(Rect(0,0,rt.Width(),rt.Height()));7rg.Exclude(&pa);8graphics.FillRegion(&SolidBrush(Color(255,0,......