11.7 CSP赛前集训小结

11.7 CSP赛前集训小结

今天是单赛日

1.上午的订正:没啥好说的

昨天的T1,稍微写下思路,维护高度差然后直接分情况讨论会很让人自闭,再加上符号+-和变化量的不同,会爆炸,那么不妨将之间的变化先减去,算上答案后再再加回来即可,正难则反的道理。

#include<stdio.h>
#include<bits/stdc++.h>
#define maxn 200005
using namespace std;
long long Ht[maxn];
long long n,q,s,t;
long long Getdel(long long x)
{
   return x > 0 ? x * s : x * t;
}
long long T=0;
int main()
{
    scanf("%lld%lld%lld%lld",&n,&q,&s,&t);
    s=-s;
    t=-t;
    for(long long i=0;i<=n;i++)
    scanf("%lld",&Ht[i]);

    for(long long i=n;i;i--)
    Ht[i]-=Ht[i-1];

    for(long long i=1;i<=n;i++)

    T+=Getdel(Ht[i]);
    long long x,y;
    long long temp;
    while(q--)
    {
        scanf("%lld%lld%lld",&x,&y,&temp);
        T-=Getdel(Ht[x]);
        T-=Getdel(Ht[y+1]);
        Ht[x]+=temp;
        if(y+1<=n)
        Ht[y+1]-=temp;
        T+=Getdel(Ht[x]);
        if(y+1<=n)
        T+=Getdel(Ht[y+1]);
        printf("%lld\n",T);
    }
}

然后就是董神讲的两道题,一道是再求最短路时DP一下,另一道则是口胡了一堆破数学公式。。然后发现题目看错了233333333

第一道的代码(本人没调,这是LCFjulao的代码)

#include<stdio.h>
#include<queue>
using namespace std;

#define INF 1000000000

int End[100005],Next[100005],Len[100005],Last[10004],tot;
int n,k,Dis[10004][12];
bool Inqueue[10005][12];
struct node{int p,t;};
bool operator<(node a,node b){return Dis[a.p][a.t]>Dis[b.p][b.t];}
priority_queue<node>q;

void Link(int x,int y,int l)
{
    tot++;
    End[tot]=y;
    Len[tot]=l;
    Next[tot]=Last[x];
    Last[x]=tot;
}

void DJ(int x)
{
    int i,j,t,y;
    node a;
    for(i=0;i<=n;i++)for(j=0;j<=k;j++)Dis[i][j]=INF;
    Dis[x][0]=0;
    a.p=x,a.t=0;
    q.push(a);
    Inqueue[x][0]=true;
    while(q.size())
    {
        x=q.top().p,t=q.top().t;
        q.pop();
        Inqueue[x][t]=false;
        for(i=Last[x];i;i=Next[i])
        {
            y=End[i];
            if(Dis[x][t]+Len[i]<=Dis[y][t])
            {
                Dis[y][t]=Dis[x][t]+Len[i];
                if(!Inqueue[y][t])
                {
                    a.p=y,a.t=t;
                    q.push(a);
                    Inqueue[y][t]=true;
                }
            }
            if(t<k&&Dis[x][t]<Dis[y][t+1])
            {
                Dis[y][t+1]=Dis[x][t];
                if(!Inqueue[y][t+1])
                {
                    a.p=y,a.t=t+1;
                    q.push(a);
                    Inqueue[y][t+1]=true;
                }
            }
        }
    }
}

int main()
{
    int m,s,t,a,b,c,i,ans=INF;
    scanf("%d %d %d",&n,&m,&k);
    scanf("%d %d",&s,&t);
    for(i=1;i<=m;i++)
    {
        scanf("%d %d %d",&a,&b,&c);
        Link(a,b,c);
        Link(b,a,c);
    }
    DJ(s);
    for(i=0;i<=k;i++)ans=min(ans,Dis[t][i]);
    printf("%d",ans);
}

然后没事干,然后就水了道树DP的题(本来该用DP做的)

#include<bits/stdc++.h>
#define maxn 10005
#define inf 999999999
using namespace std;
/*
结论:树上任意一点的最长距离一定是到直径某一端点的距离
因此此题可以先通过该结论求出树的直径
求法:找任意一个点求出该点的最远距离点T
由结论可知T一定是树直径的端点,再求离T最远的点S,由结论又可知S也是端点
所以ST即为树的直径,然后再用一遍结论,本题中每个点的最远距离即为max(dis【S】,dis【T】);
要用到两次结论做本题,有点意思
*/
struct node
{
    int To,Len;
};
vector<node> Map[maxn];
int Max_Dis=-inf;
int S=0;
int Type=0;
int Dis_S[maxn];
int Dis_T[maxn];
void Dfs1(int pos,int fa,int Dis)
{
//    cout<<Dis<<endl;
    if(Type==1)
    {
        Dis_S[pos]=Dis;
    }
    if(Type==2)
    {
        Dis_T[pos]=Dis;
    }
    if(Dis>=Max_Dis)
    {
        S=pos;
        Max_Dis=Dis;
    }
    for(int i=0;i<Map[pos].size();i++)
    {
        if(Map[pos][i].To!=fa)
        Dfs1(Map[pos][i].To,pos,Dis+Map[pos][i].Len);
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    node temp;
    int x,y;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        temp.To=x;
        temp.Len=y;
        Map[i+1].push_back(temp);
        temp.To=i+1;
        Map[x].push_back(temp);
    }
    Type=0;
    Dfs1(1,1,0);
    int SS=S;
    Max_Dis=-inf;
    S=0;
    Type=1;
    Dfs1(SS,SS,0);
    int TT=S;
    Type=2;
    Max_Dis=-inf;
    Dfs1(TT,TT,0);
    for(int i=1;i<=n;i++)
    {
        printf("%d\n",max(Dis_T[i],Dis_S[i]));
    }
}

原文地址:https://www.cnblogs.com/pveds/p/11811306.html

时间: 2024-10-08 08:54:39

11.7 CSP赛前集训小结的相关文章

11.8 CSP赛前集训

  今天还是单赛?? emmmmm上午改题ing,没啥好说的,昨天那道被卡spfa的题改过了.看了道树形Dp的题想着用贪心去做.感觉没啥毛病,也找不出啥反例,码了良久结果.. 然后听了三道神仙题目,自闭ing.没了 QAQ,我好菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜菜

【2017.11.07】noip赛前集训 | T1 遭遇【DP】

T1 遭遇 [题意] ??座楼房,立于城中. 第??座楼,高度???. 你需要一开始选择一座楼,开始跳楼.在第??座楼准备跳楼需要????的花费. 每次可以跳到任何一个还没有跳过的楼上去.但跳楼是有代价的,每次跳到另 外一座楼的代价是两座楼高度的差的绝对值,最后一次从楼上跳到地面上不需 要代价(只能跳到地上一次).为在代价不超过??的情况下,最多跳几次楼. (一座楼只能跳一次,且每次跳楼都要计算准备的花费) [题解] 跳楼时,楼房的高度是具有单调性的,所以先按照高度排序. f[i][j]表示已经

2017.11.26【清华集训2017】模拟

T1 5483. [清华集训2017模拟11.26]简单路径T2 5484. [清华集训2017模拟11.26]快乐树T3 5485. [清华集训2017模拟11.26]字符串 T1 结论题,结论很显然任意两条路径权异或后,会将两条路径的交的贡献删去.然后用个桶存一下出现过的异或和,暴力判一下就可以了 code 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<algorithm

[CSP校内集训]贪吃蛇(阿尔法-贝塔剪枝)

题目 有两条蛇(1号蛇和2号蛇)在n行m列的地图上,地图上有障碍物.一条蛇碰到蛇身/障碍物/边界就会死.蛇身会不断长长--可以理解为蛇尾位置不会变,蛇只会向前伸展不会缩尾巴.两条蛇都绝顶聪明,如果自己能赢,一定会尽量快地赢;如果自己会输,一定会死得尽量晚.给出初始局面,两蛇轮流走,每次可以且必须向上下左右移动一格.1号蛇先走,请告诉我谁会在多少回合时赢.\((n,m\leq 20)\)且\(0\)的数量不超过\(50\) \(\alpha - \beta\)剪枝 AlphaBeta剪枝算法是一个

[CSP校内集训]attack(DAG支配树)

题意 给一个DAG,多次询问,每次给定\(k\)个点,求1到这些点的必经点的交集大小 思路 支配树裸题,建好DAG的支配树后\(k\)个点LCA的深度即为答案 Code #include<bits/stdc++.h> #define N 100005 using namespace std; int n,m,q; int rd[N],f[N][18],dep[N]; struct Edge { int next,to; }edge[N<<1],edge1[N<<1];i

[CSP校内集训]tree(期望DP)

题意 给一颗树,从1节点出发,走每条边的概率相同且耗时为1,求每个点第一次被遍历到的期望时间(\(t_1=1\)) 思路 在树上只有两种移动方式:从儿子到父亲,从父亲到儿子 假设从\(rt\)走到\(v\)的期望代价为\(dow_i\),从\(i\)走到\(rt\)的期望代价为\(val_i\) 假设从\(rt\)转移到\(v\),\(rt\)的度数为\(k\),\(rt\)的父亲为\(fa\),则: \[dow_v = \frac{1}{k} + \sum_{son}^{son\neq v}

[CSP校内集训]rank

题意 给出一个字符串后缀排序之后的数组\(sa_i\),求原字符串(字典序最小),无解输出-1 思路 显然从\(rk_1\)开始填字符是可以保证字符单调不降的 找到\(sa\)值相邻的两个位置,现在需要知道\(rk_i\)和\(rk_{i+1}\)是否可以填相邻字符:当它们填相同字符时需要比较后一位,如果相对关系相同则可行(因为后一位默认已经成立) 举个栗子:\(4,2,3,1\),查看4能不能和3填同一个字符,则判断后一位2和1:而\(4>3 \&\& 2>1\),所以可以相

2019/11/1 CSP模拟

写在前面的反思 该拿的部分分还是得拿完啊,因为懒+动作慢没有写最后一道题的菊花图和链的情况,其实这两个点并不难.. 虽然只有\(10pts\),但是已经足够往上爬一截了啊,额外的\(10pts\)在今天大众分\(210pts\)的背景下显得好重要 另外\(T2\)下来发现最后判断的地方假了,所幸好像它能跑得动的数据范围内都没出问题,但要卡还是很好卡,只是这次运气好没被卡而已,下次写的时候还是要注意,正式比赛不一定就不卡了 T1 \(sb\)题 对于\(b==1\),判断所有总数的\(gcd\)能

[CSP校内集训]矩形面积交(树状数组)

题意 给\(n\)个互不相交的矩形,再给\(m\)个询问,每次给一个矩形求它与这\(n\)个矩形的面积交 思路 自己写的太丑了导致DEBUG了一个半小时qwq 一对矩形的交可以拆分成二维前缀和形式下的矩形的交,于是变成判断16次矩形的交(不想画图...只想口胡) 这些矩形都有\(x_0=0,y_0=0\),即左下角为坐标原点,于是一个矩形可以只用右上角的坐标表示: 对于一个询问的矩形\((x,y)\)和另一个矩形\((x_i,y_i)\),它们的交为\(min(x,x_i)\times min(