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

CSP 模拟 38

时间:2024-10-08 19:36:30浏览次数:1  
标签:std 38 return rs int mid ls CSP 模拟

A score and rank

神秘贪心,如果全是正数,每当大于等于 \(S\) 时删除最大的最优。如果 \(S\) 是负数,删去所有大于等于的数就是答案。
思考删除最大的为什么不对,会有这样的情况,一个负数很小,使得选择区间改变,导致维护的集合清空。这时可以选择拿正数来抵消负数。
具体来说,当前 \(sum\) 加上 \(x\) 后如果小于等于 \(0\) 直接清空,重新选择,否则不断拿当前集合中最小的数来抵消这个负数,贪心保证以后的删除仍然去删大数,拿 std::multiset 维护即可。

B HZOI大作战

维护单调栈卡空间,过不了。直接预处理出从每个点跳到根要更换多少次,再倍增求出大于当前数的位置,再减去第一个在祖先之上大于路径 \(max\) 的位置的次数即可。

C Delov的旅行

最大值最小,考虑二分答案,按 dfs 序遍历一定不劣,发现对于每棵子树,只有进去的第一个叶子和最后一个叶子返回会对外界产生影响,考虑设 \(f_{u,i,j}\) 表示在 \(u\) 的子树内,前往的第一个叶子距离是 \(i\),最后一个叶子的距离是 \(j\),中间的代价是否都小于等于 \(mid\),状态数爆炸,但是对于 \(i_1\le i_2,j_1\le j_2\),\((i_2,j_2)\) 是没有用处的,因为有比他更优且可行的方案,所以总状态数只有叶子个。
所以随着 \(i\) 的增大,\(j\) 一定变小,用 set 维护状态,因为有上述单调性,合并子树可以直接双指针,在满足中间条件的同时尽量选择回来代价小的,所以我们找到最大的 \(i\) 即可。注意第一天去和第二天回可以不满足限制。

#include<bits/stdc++.h>
#define int long long
#define fo(i,s,t) for(int i=s;i<=t;++i)
typedef long long ll;
typedef unsigned long long ull;
inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;}
const int N=1.5e5;
int n;
struct EDGE{int v,w;};
std::vector<EDGE> e[N];
struct NODE{
    int a,b;
    friend bool operator<(const NODE &a,const NODE &b){
        return a.a==b.a?a.b<b.b:a.a<b.a;
    }
}zc[N];
std::set<NODE> s[N];
inline bool dfs(int x,int fa,int mid){
    s[x].clear();
    int ls=0,rs=0,vl,vr;
    for(auto it:e[x]){
        int v=it.v,w=it.w;if(v==fa)continue;
        if(!dfs(v,x,mid))return 0;
        if(ls)rs=v,vr=w;
        else ls=v,vl=w;
    }
    if(!ls&&!rs){s[x].insert({0,0});return 1;}
    int cnt=0;
    auto it=s[rs].begin(),en=--s[rs].end();
    for(auto now:s[ls]){
        while(it!=en&&(*next(it)).a+now.b+vl+vr<=mid)++it;
        if((*it).a+now.b+vl+vr<=mid)zc[++cnt]={now.a+vl,(*it).b+vr};
    }
    it=s[ls].begin(),en=--s[ls].end();
    for(auto now:s[rs]){
        while(it!=en&&(*next(it)).a+now.b+vl+vr<=mid)++it;
        if((*it).a+now.b+vl+vr<=mid)zc[++cnt]={now.a+vr,(*it).b+vl};
    }
    if(!cnt)return 0;
    std::sort(zc+1,zc+cnt+1);
    s[x].insert(zc[1]);
    int las=1;
    for(int i=2;i<=cnt;++i)
        if(zc[i].b<zc[las].b&&zc[i].a>zc[las].a)s[x].insert(zc[i]),las=i;
    if(s[x].empty())return false;
    return true;
}
signed main(){
    freopen("trip.in","r",stdin);freopen("trip.out","w",stdout);
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
    n=read();
    int l=0,r=0,res=0;
    for(int i=2;i<=n;++i){
        int u=read(),w=read();e[u].push_back({i,w});e[i].push_back({u,w});
        r+=w;
    }
    while(l<=r){
        int mid=l+r>>1;
        if(dfs(1,0,mid))r=mid-1,res=mid;
        else l=mid+1;
    }
    std::cout<<res<<'\n';
}

D gtm 和 joke的星球

斯坦纳树模板。
最后选出来的子图是一棵树,设 \(f_{i,S}\) 表示以 \(i\) 为根,联通 \(S\) 集合的最小代价,有两种情况的转移,一种是根的度数为 \(1\),\(f_{i,S}=f_{j,S}+w(i,j)\),另一种是不唯一,考虑拼接起来,有 \(f_{i,S}=f_{i,T}+f_{i,S-T}\)。
第一个转移和最短路的转移方程一样,最短路即可,第二种转移枚举子集即可,时间复杂度 \(\mathcal{O}(n3^k+n^22^k)\)。

标签:std,38,return,rs,int,mid,ls,CSP,模拟
From: https://www.cnblogs.com/Ishar-zdl/p/18452340

相关文章

  • csp-s 模拟 8
    csp-s模拟8T1scoreandrank特殊性质,题意转换妙妙题对于\(S\)小于等于\(0\)的情况答案显然是所有大于等于\(S\)的个数。现在讨论\(S\)大于\(0\)的情况。先对序列做一个前缀和,题目要求即是让所有值减去前缀最小值小于\(S\)考虑有一段连续正整数的和大于\(S\),则......
  • XYD1005CSPS
    T1传送门[最短路,二分答案]Description无向连通图,求出一个最小的\(x\),使得每两点之间存在一条路径可以划分成不超过\(k\)段路径,且每段路径长度不超过\(x\),只能从节点处切割,不能从边中间划分。\(n\le100\),无重边自环。Solution\(n\)非常小,又要考虑每两个点,自然想到全......
  • 3.搜索、模拟
    搜索、模拟\(A\)luoguP1120小木棍\(B\)luoguP2540[NOIP2015提高组]斗地主加强版\(C\)CF58EExpression\(D\)CF293BDistinctPaths\(E\)[ABC352F]EstimateOrder\(F\)[ABC336F]RotationPuzzle\(G\)CF525EAnyaandCubes\(H\)luoguP9234买瓜\(I\)......
  • csp-s模拟10
    csp-s模拟10\(T1\)T3673.欧几里得的噩梦\(0pts\)部分分\(0\%\):状压加枚举子集。\(20\%\):线性基暴力做。正解\(T2\)T3672.清扫\(6pts\)原题:[AGC010C]Cleaning钦定根节点\(rt\)的度数\(\ge2\),所以需要特判\(n=2\)的情况。部分分未知\(pt......
  • csp-s模拟10
    rank31,垫底了,T10pts,T218pts,T30pts,T450pts状态有点不好,策略有问题,T4是可以切的,但是不知道为什么弃了。T1不会线性基寄。T3奇怪结论题,T2结论题。在猜结论上还是不行。T1欧几里得的噩梦用到了线性基线性无关的性质,将两个数连边,把环去掉,并查集判断即可。统计答案用快速......
  • Linux csplit命令
    csplit命令在Linux中用于将文件分割成多个部分,基于指定的模式或固定数量的行。与split命令不同,csplit允许更复杂的分割条件,例如基于正则表达式匹配或特定字符的出现次数。基本语法csplit[选项]文件名模式文件名:要分割的文件。模式:分割文件的依据,可以是正则表达式或数字。......
  • Day1 备战CCF-CSP练习
    Day1201403-1问题描述有$N$个非零且各不相同的整数。请你编一个程序求出它们中有多少对相反数($a$和$-a$为一对相反数)。输入格式第一行包含一个正整数$N$。$(1≤N≤500)$。第二行为$N$个用单个空格隔开的非零整数,每个数的绝对值不超过$1000$,保证这些整数各......
  • 『模拟赛』CSP-S模拟10
    Rank没学线性基输麻了,A.欧几里得的噩梦线性基,输麻了。B.清扫思维题,差点签了。(感觉其实不是很难啊,没有紫的水平)一个叶子结点和另一个叶子结点的最短路径一定经过它的父节点。根据这一性质可以让整棵树的合法性拆分成每个节点的合法性。考虑如何判断每个节点的合法性。......
  • 数据清洗 微信:a1319614038
    #stata数据清洗整理合并筛选匹配#excel数据匹配合并筛选匹配#python数据清洗整理合并筛选匹配抓取,请直接说明具体要求发给我,我会第一时间回复你,#vlookup函数应用,vlookup功能实现,#CSV文件处理,超大文件,超过显示,#拆分,统计,批量处理,大量数据文件合并,#匹配合并,矩阵文件,各种问题解决。数......
  • [43] (CSP 集训) CSP-S 模拟 10
    B.清扫考虑从叶子节点往上推首先可以发现的几个性质子树内需要消除的数,要么通过子树根节点“发送”到上面(只经过子树内一个叶节点),要么通过自己的叶节点解决对于子树内既不是根也不是叶节点的节点,节点上的值只能由这一支路的叶节点消除,所以如果他节点上的值和下面节点“发......