由于咕掉的题解太多了,所以只能趁改完不动题的时间,来补补坑qwq,还是太弱了。

考试过程:

到新机房的第一次考试,貌似海星?

第一题一开始就觉得是个贪心,但以为所有小怪兽都要打完,所以想复杂了,但后来发现只要每个人都有怪兽打就吼了,然后显然二分答案,1h 打完。

T2没什么思路,想拆柿子,但没什么用,只qj了链的测试点,用来跑所有测试点竟然得了40pts。

T3一眼看错题,然后一眼wqs二分,然后调到考试结束也没调出样例。

题解:

T1 kill:

先把人和怪兽得坐标sort一下。

显然这n个人打怪兽的最长时间是单调的,然后直接二分答案即可,check时贪心的选择前面的怪兽。

 #include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=;
int mon[N],per[N];
int maxn;
int n,m,s;
bool check(int mid){
int res=,now=;
for(int i=;i<=n;++i){
while(now<=m&&mid<abs(mon[now]-s)+abs(per[i]-mon[now])) ++now;
// res+=abs(mon[now]-s)+abs(per[i]-mon[now]);
if(now>m/*n||m*/) return ;now++;
}
return ;
} signed main(){
scanf("%lld%lld%lld",&n,&m,&s);
for(int i=;i<=n;++i) scanf("%lld",&per[i]);
for(int i=;i<=m;++i) {scanf("%lld",&mon[i]);maxn=max(maxn,mon[i]);}
int l=,r=maxn;
sort(per+,per+n+);
sort(mon+,mon+m+);
int ans=;
while(l<=r){
// cout<<l<<" "<<r<<endl;
int mid=(l+r)>>;
if(check(mid)) r=mid-,ans=mid;
else l=mid+;
}
printf("%lld",ans);
}
/*
//jia tanxin
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5005;
int per[N],mon[N],cost[N];
vector<int > ve[N];
set<int > s[N];
int max(int a,int b){
return a>b?a:b;
} signed main(){
//freopen("data.in","r",stdin);
//freopen("1.out","w",stdout);
int n,m,s;
scanf("%lld%lld%lld",&n,&m,&s);
for(signed i=1;i<=n;++i) scanf("%lld",&per[i]);
for(signed i=1;i<=m;++i) scanf("%lld",&mon[i]);
for(signed i=1;i<=m;++i){
cost[i]=abs(mon[i]-s);
}
for(signed i=1;i<=n;++i){
for(signed j=1;j<=m;++j){
ve[i].push_back(cost[j]+abs(per[i]-mon[j]));
}
}
for(signed i=1;i<=n;++i){
sort(ve[i].begin(),ve[i].end());
}
int ans=0;
for(signed i=1;i<=n;++i){
ans=max(ans,*ve[i].begin());
}
printf("%d",ans);
}
*/

kill

T2 beauty:

类似于换根dp的思路,分别考虑子树内和子树外的点对产生的贡献,记$cnt[x]$ 为以$x$为根节点的子树内关键点的个数,那么对于,每个点,考虑所有的关键点在这一个点产生的贡献,子树内有$cnt[x]$个,那么子数外就有$2*k-cnt[x]$个,那么这些点配对的话,经过这一个点,即经过一个单位的距离,产生贡献就是$min(cnt[x],2*k-cnt[x])$,$dfs$一遍即可。

 #include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+;
int d[N],fa[N][];
int first[N],nex[N<<],to[N<<],tot;
int ka[N],ver[N],du[N],Root;
int mark[N],cnt[N];
int dp[N];
int n,k,QJ,ans;
struct Ver{
int dep,id;
}p[N];
bool cmp(Ver a,Ver b){
return a.dep<b.dep;
}
void add(int a,int b){
to[++tot]=b,nex[tot]=first[a],first[a]=tot;
}
queue<int > q;
void bfs(){
d[Root]=;
q.push(Root);
while(q.size()){
int x=q.front();q.pop();
for(int i=first[x];i;i=nex[i]){
int y=to[i];
if(d[y]) continue;
d[y]=d[x]+;
fa[y][]=x;
for(int j=;j<=;++j) fa[y][j]=fa[fa[y][j-]][j-];
q.push(y);
}
}
}
int Lca(int x,int y){
if(d[x]>d[y]) swap(x,y);
for(int i=;i>=;--i) if(d[fa[y][i]]>=d[x]) y=fa[y][i];
if(x==y) return x;
for(int i=;i>=;--i) if(fa[y][i]!=fa[x][i]) y=fa[y][i],x=fa[x][i];
return fa[x][];
}
void pre_dfs(int x,int fa){
if(mark[x]) cnt[x]=;
for(int i=first[x];i;i=nex[i]){
int y=to[i];
if(y==fa) continue;
pre_dfs(y,x);
cnt[x]+=cnt[y];
}
} void dfs(int x,int fat){
if(mark[x]) cnt[x]++;
for(int i=first[x];i;i=nex[i]){
int y=to[i];
if(y==fat) continue;
dfs(y,x);
cnt[x]+=cnt[y];
}
ans+=min(cnt[x],k*-cnt[x]);
// dp[fa[x][0]]=min(dp[x],k*2-cnt[x]);
} signed main(){
scanf("%lld%lld%lld",&n,&k,&QJ);
const int bz=k<<;
for(int i=;i<=bz;++i) {scanf("%lld",&ver[i]);mark[ver[i]]=;}
for(int i=;i<n;++i){
int x,y;
scanf("%lld%lld",&x,&y);
add(x,y);
add(y,x);
du[x]++,du[y]++;
}
if(QJ){
for(int i=;i<=n;++i){
if(du[i]==){
Root=i;
break;
}
}
bfs();
for(int i=;i<=bz;++i){
ka[i]=d[ver[i]];
p[i].dep=d[ver[i]];
p[i].id=ver[i];
}
sort(p+,p+k*+,cmp);
for(int i=;i<=k;++i){
ans+=abs(p[i].dep+p[bz-i+].dep-*d[Lca(p[i].id,p[bz-i+].id)]);
}
printf("%lld",ans);
}
else{
Root=;
memset(dp,0x7f,sizeof(dp));
dfs(,);
printf("%lld",ans);
}
}
/*
7 2 0
1 5 6 2
1 3
3 2
4 5
3 7
4 3
4 6
*/

beauty

T3 wight:

考试时看错题,以为只要有一个最小生成树包含那条边即可,但实际上是要所有的最小生成树都要包含那条边。

我们可以先用kruscal 跑出一个最小生成树,那么他现在树边已经在最小生成树上了,所以我们对树边和非树边进行分类讨论。

对于非树边,因为只有树边才会被他替换下去,所以我们考虑树边对他的影响,考虑这条非树边两个端点的简单路径,加上这条非树边就会构成一个环,对于一个环,任意去掉一条边他还能够连接起n个点,所以这条非树边只要不是这个环上最大权值就可以,即MST上路径最大权值,树剖维护即可,然后把这条非树边本来的权值更新到线段树里边,后面树边情况要用到。

对于树边,我们考虑非树边对他的影响,同上,所有能够与他成环的非树边,只要有权值比他小的,就可以把它替换掉,所以每条树边的答案是所有与他成环的非树边的最小值减一,还是树剖维护。

注意:

  1. 要先更新完所有的非树边再更新树边,因为你不知道那条非树边会对那条树边产生影响。
  2. 各种编号的转化一定要搞清楚。
  3. 关于线段树的操作,建树和询问维护的是树边`最大值,更新和懒标记下传是非树边`最小值。
     #include<bits/stdc++.h>
    using namespace std;
    const int INF=1e9;
    const int N=1e6+;
    int first_f[N],tot,first[N],tot_c,ans[N];
    int n,m;
    int rcd[N];
    struct Edge{
    int fr,to,nex,val,id,v;
    }e[N<<];
    struct EDGE{
    int fr,to,nex,val,id;
    }ee[N<<]; struct SegmentTree{
    int l,r,lazy,mx,mi;
    }tr[N<<];
    int f[N];
    int get(int x){
    if(f[x]==x) return x;
    return f[x]=get(f[x]);
    } void add(int x,int y,int z,int k){
    e[tot].id=k,e[tot].to=y,e[tot].fr=x;
    e[tot].nex=first_f[x],e[tot].val=z,first_f[x]=tot++;
    // e[tot].to=b,e[tot].id=kl,e[tot].fr=a,e[tot].nex=first_f[a],e[tot].val=c,first_f[a]=tot++;
    }
    bool cmp(Edge a,Edge b){
    return a.val<b.val;
    }
    void add_c(int a,int b,int c,int kl){
    ee[tot_c].to=b,ee[tot_c].nex=first[a],ee[tot_c].val=c,ee[tot_c].id=kl,first[a]=tot_c++;
    } int fa[N],d[N],size[N],son[N],wt[N];
    void dfs1(int x,int fat){//cout<<x<<endl;
    size[x]=;
    for(int i=first[x];i!=-;i=ee[i].nex){
    int y=ee[i].to;
    if(y==fat) continue;
    d[y]=d[x]+;//cout<<x<<" "<<y<<endl;
    fa[y]=x;
    wt[ee[i].to]=ee[i].val;
    rcd[ee[i].to]=ee[i].id;
    dfs1(y,x);
    size[x]+=size[y];
    if(size[y]>size[son[x]]) son[x]=y;
    }
    }
    int id[N],top[N],cnttt,pos[N];
    void dfs2(int x,int topf){//cout<<x<<" "<<topf<<endl;
    top[x]=topf;
    id[x]=++cnttt;
    pos[cnttt]=x;
    if(son[x]) dfs2(son[x],topf);
    for(int i=first[x];i!=-;i=ee[i].nex){
    int y=ee[i].to;
    if(y==fa[x]||y==son[x]) continue;
    dfs2(y,y);
    }
    }
    void down(int p){
    if(tr[p].lazy==INF+) return ;
    tr[p<<].lazy=min(tr[p<<].lazy,tr[p].lazy);
    tr[p<<|].lazy=min(tr[p<<|].lazy,tr[p].lazy);
    tr[p<<].mi=min(tr[p].lazy,tr[p<<].mi);
    tr[p<<|].mi=min(tr[p].lazy,tr[p<<|].mi);
    tr[p].lazy=INF+;
    } void build(int p,int l,int r){
    tr[p].l=l,tr[p].r=r,tr[p].lazy=INF+;
    if(l==r){
    tr[p].mi=INF+;
    tr[p].mx=wt[pos[l]];
    return ;
    }
    int mid=(l+r)>>;
    build(p<<,l,mid);
    build(p<<|,mid+,r);
    tr[p].mx=max(tr[p<<].mx,tr[p<<|].mx);
    }
    int q_mx=;
    void update(int p,int l,int r,int ll,int rr,int val){//cout<<"U "<<p<<endl;
    if(ll<=l&&r<=rr){
    tr[p].mi=min(tr[p].mi,val);
    tr[p].lazy=min(tr[p].lazy,val);
    return ;
    }
    down(p);
    int mid=(tr[p].l+tr[p].r)>>;
    if(ll<=mid) update(p<<,l,mid,ll,rr,val);
    if(rr>mid) update(p<<|,mid+,r,ll,rr,val);
    tr[p].mi=min(tr[p<<].mi,tr[p<<|].mi);
    }
    void query(int p,int l,int r,int ll,int rr){//cout<<p<<" "<<l<<" "<<r<<" "<<ll<<" "<<rr<<endl;
    if(ll<=l&&r<=rr){
    q_mx=max(q_mx,tr[p].mx);
    return ;
    }
    down(p);
    int mid=(tr[p].l+tr[p].r)>>;
    if(ll<=mid) query(p<<,l,mid,ll,rr);
    if(rr>mid) query(p<<|,mid+,r,ll,rr);
    }
    void Update(int x,int y,int val){
    while(top[x]!=top[y]){//cout<<x<<" "<<y<<endl;
    if(d[top[x]]<d[top[y]]) swap(x,y);
    update(,,n,id[top[x]],id[x],val);
    x=fa[top[x]];
    }
    if(d[x]>d[y]) swap(x,y);
    update(,,n,id[x]+,id[y],val);
    }
    int ans_mi=0x7fffffff,ans_mx=;
    int Ask(int x,int y){
    q_mx=,ans_mx=;
    while(top[x]!=top[y]){//cout<<x<<" "<<y<<endl;
    if(d[top[x]]<d[top[y]]) swap(x,y);
    q_mx=;
    query(,,n,id[top[x]],id[x]);
    ans_mx=max(ans_mx,q_mx);
    x=fa[top[x]];
    }//cout<<"K"<<endl;
    if(d[x]>d[y]) swap(x,y);
    q_mx=;
    query(,,n,id[x]+,id[y]);
    ans_mx=max(ans_mx,q_mx);
    return ans_mx;
    } void db(int p){
    cout<<tr[p].l<<" "<<tr[p].r<<" "<<tr[p].mx<<endl;
    if(tr[p].l==tr[p].r){
    return ;
    }
    db(p<<);db(p<<|);
    }
    void solve(int p){
    if(tr[p].l==tr[p].r){
    ans[rcd[pos[tr[p].l]]]=tr[p].mi-;
    if(ans[rcd[pos[tr[p].l]]]==INF){
    ans[rcd[pos[tr[p].l]]]=-;
    }
    return ;
    }
    down(p);
    solve(p<<);solve(p<<|);
    } int main(){
    int Suarez;
    memset(first,-,sizeof(first));
    scanf("%d%d%d",&n,&m,&Suarez);
    for(int i=;i<=n;++i) f[i]=i;
    for(int i=;i<=m;++i){
    int x,y,z;
    scanf("%d%d%d",&x,&y,&z);
    add(x,y,z,i);
    // add(y,x,z,i);
    }
    sort(e+,e+tot,cmp);
    int sum=;
    for(int i=;i<tot;i++){
    int x=(get(e[i].fr)),y=get(e[i].to);
    if(x!=y){//cout<<i<<" ";
    if(get(x)!=get(y)) f[x]=y;
    sum++;
    e[i].v=;
    add_c(e[i].fr,e[i].to,e[i].val,e[i].id);
    add_c(e[i].to,e[i].fr,e[i].val,e[i].id);
    }
    if(sum==n-) break;
    }
    d[]=;
    dfs1(,);//cout<<"Dfs1"<<endl;
    dfs2(,);//cout<<"dfs2"<<endl;
    build(,,n);//cout<<"build"<<endl;
    // db(1);
    // for(int i=1;i<=n;++i) cout<<first[i]<<" ";
    // puts("");
    // for(int i=0;i<tot;++i) cout<<e[i].v<<" ";
    // for(int i=1;i<=n;++i) cout<<top[i]<<" ";
    // cout<<endl;
    // for(int i=1;i<=n;++i) cout<<fa[i]<<" ";
    // for(int i=1;i<=n;++i) cout<<wt[pos[i]]<<" ";
    // cout<<endl;
    // cout<<tot<<endl;
    // for(int i=1;i<=n;++i) cout<<son[i]<<" ";
    // cout<<endl;
    for(int i=;i<tot;i++){
    // if(i==19) cout<<"L"<<endl;
    // if(i==tot-1) cout<<"L"<<endl;
    // if(i>40) cout<<e[i].v<<" ";
    if(e[i].v==){//cout<<i<<endl;
    ans[e[i].id]=Ask(e[i].fr,e[i].to)-;//cout<<"ask"<<endl;
    Update(e[i].fr,e[i].to,e[i].val);//cout<<"upd"<<endl;
    }
    }
    // for(int i=0;i<tot;++i) cout<<e[i].v<<" ";
    solve();
    for(int i=;i<=m;++i){
    printf("%d ",ans[i]);
    }
    }
    /*
    4 4 0
    1 2 1
    2 3 1
    3 4 1
    4 1 2 out 1 1 1 0 4 3 0
    1 2 2
    2 3 2
    3 4 2 out -1 -1 -1 */

    wight

CSP-S 模拟测试 45 题解的更多相关文章

  1. [CSP-S模拟测试45]题解

    开局一行$srand$,得分全靠随机化. A.kill 发现两个并不显然的性质: 1.选中的人和怪物一定是按顺序的.第一个人打所有被选中怪物的第一只,第二个人打第二只,$etc$. 2.最优方案打的怪 ...

  2. CSP-S 模拟测试94题解

    T1 yuuustu: 可以对两边取对数,然后就转化为两个double的比较,时间复杂度$O(n)$ 然后我就用神奇0.4骗分水过 #include<bits/stdc++.h> usin ...

  3. CSP-S模拟测试 88 题解

    T1 queue: 考场写出dp柿子后觉得很斜率优化,然后因为理解错了题觉得斜率优化完全不可做,只打了暴力. 实际上他是可以乱序的,所以直接sort,正确性比较显然,贪心可证,然后就是个sb斜率优化d ...

  4. CSP-S 模拟测试92 题解

    话说我怎么觉得我没咕多长时间啊,怎么就又落了20多场题解啊 T1 array: 根据题意不难列出二元一次方程,于是可以用exgcd求解,然而还有一个限制条件就是$abs(x)+abs(y)$最小,这好 ...

  5. CSP-S 模拟测试57题解

    人生第一次A,B层一块考rank2,虽然说分差没几分,但还是值得纪念. 题解: T1 天空龙: 大神题,因为我从不写快读也没有写考场注释的习惯,所以不会做,全hzoi就kx会做,kx真大神级人物. T ...

  6. CSP-S 模拟测试 51 题解

    考试过程: 惯例先看一遍三道题,T1 一开始反应要求割点,但是这是有向图,肯定不能求割点,康了一下数据范围,有40%是树的,还不错,决定待会在打. 看T2 字符串题,完了我字符串最弱了,肯定只能打暴力 ...

  7. [CSP-S模拟测试110]题解

    也许是最后一篇了. A.最大或 不错的签到题. 对于二进制位来说,高位的一个1比低位的所有1的贡献总和还要大. 显然,$r$必选,因为$r$中所有1的相对考前.那么考虑如何构造另一个数. 首先$l$和 ...

  8. [CSP-S模拟测试97]题解

    A.小盆友的游戏 感觉题解解释的很牵强啊……还是打表找规律比较靠谱 对于每个人,它构造了一个期望函数$f(x)$,设它的跟班个数为$cnt[x]$,那么令$f(x)=2^{cnt[x]}-1$(??鬼 ...

  9. [CSP-S模拟测试96]题解

    以后不能再借没改完题的理由不写题解了…… A.求和 求$\sum \sum i+j-1$ 柿子就不化了吧……这年头pj都不考这么弱智的公式化简了…… 坑点1:模数不定,可能没有2的逆元,那么只要先把乘 ...

随机推荐

  1. python 基础例子 双色球 查询天气 查询电话

    # 随机生成双色球import random# 随机数 1-16之间# r = random.randint(1,16)# print(r)phone_numbers_str = "匪警[1 ...

  2. C++11 bind和function用法

    function是一个template,定义于头文件functional中.通过function<int(int, int)> 声明一个function类型,它是“接受两个int参数.返回 ...

  3. Asp.net core 学习笔记 QR code and Barcode

    QR code 和 Barcode 经常会使用到. Java 阵营有著名的 zxing https://github.com/zxing/zxing .Net 有对接它的 port https://g ...

  4. mac 下 vscode配置SFTP连接

    VScode中使用SFTP插件连接远程服务器进行文件修改 下载SFTP插件后,使用Ctrl+Shift+P.输入SFTP,选择第一个将会生成简短的默认配置文件 然后把sftp.json文件内内容换成以 ...

  5. 守护服务Supervisor的安装和使用

    Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统 ...

  6. SQLServer从渣仔到小白

    一.将查询结果插入到另一张表 1. 查询结果插入新表 select * into tableA from tableB where … 2. 查询结果插入已经存在的表 insert into tabl ...

  7. adb实操

    一.命令 adb connect IP:5555 adb disconnect IP:5555 adb remount adb install 安装包的绝对路径 二.获取logcat信息 1.制作文件 ...

  8. 《Linux就该这么学》day4-6

    继续学习打卡,这几天有事所以看视频补上了这几天的学习进度. day4:主要重点 tar打包和解压命令 tar -zxvf  xxx.tar.gz 解压xxx.tar.gz   (将xxx.tar.gz ...

  9. Django模型层:单表操作,多表操作,常用(非常用)字段和参数,Django-model进阶

    一.web应用 二.模板的导入与继承 三.静态文件相关 四.inclusion_tag:返回html片段 五.模型层 一.web应用 -s包括两个部分:web服务器+application -目前阶段 ...

  10. 关于JPype报FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm'错误的解决

    部署到线上的项目正常运行一年,今天早上突然报FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm'错误. JPyp ...