HKHbest

HZ 游记


Day -1

收拾东西,准备出发。
话说这几天一直比较懒,也没什么心情和效率学习,颓废好几天了,希望到衡水以后能感觉好点。
不知道衡水有没有妹子
非常想看看衡水的样子,但是又害怕封闭式教学QWQ。
不过不知道为什么总感觉,接下来在衡水除了学OI还会得到些很重要的东西。
(预言flag)
QAQ


Day 0

晕车1小时到南站,差点吐到车上。
到了以后一个人也没没到,开始调教输入法。
看Alan火柴人一直到Cyber_tree十点多来。
车上玩一会阿瑞斯病毒玩一会群星有点晕,Cyber_tree巨佬在旁边吃零食看漫画追番。
(白嫖了薯片)
路上:莫名其妙拉着Cyber_tree和我去餐车逛街了(我就看看,不买)。

然而下动车以后一下不快乐了起来。
火车站出站口一群黑车拉生意,想到知乎上一个问题:
Q:女人如何才能让男人为你挣风吃醋?
A:去火车站打黑车。
于是和星光0000、SpadeA261一起在YPJ弄车的时候快乐玩起了双人三人跳一跳(然而每一次都是我死)
来车以后怕晕车于是安静在副驾驶听歌。
到HZ后发了个朋友圈,仿星光0000的文案:

成功到达
下一步
成功逃跑

然后放了一下行李突然就被叫走去上课,网络流。
啊这我还没吃午饭
上课,碰到久仰的巨佬赵思远(竟然就坐我旁边!!!)、杨卓凡,高俊垚、吴孟周。
SPFA他们竟然不读死趴法
不过最后1h太饿了都没好好听课
早知道就在餐车真香了……
去了食堂,意外发现HZ没有我想象的那么卷,没人吃饭的时候学习,都在看奥运(食堂电视),不过他们也没多长吃饭时间。
发现HZOI有妹子
发现HZ电脑比SDFZ还烂
发现HZ校服很简单但显身材
发现HZ女孩子还挺有颜值
发现我想买一套HZ校服

晚上回机房打代码。
交流了一会Linux,写了一会负圈没成功去找A神要了道上下界网络流的题

题解
显然这道题就是每条雪道下界为 $1$ 的最小流,那么按照上下界网络流的套路,先钦定下界流量。之后再通过超级源汇点补全亏欠的流量,之后 $t->s$ Dinic将可行流转化为最小流。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=300,INF=0x7fffffff,M=11000;
int n,dis[N],m,s,t,head[N],cnt=1,cur[N],in[N],out[N],S,T,xs,xt,ans,dep[N];
bool inq[N],vis[N];
struct bian
{
    int nxt,to,w,c;
}b[M];
void add(int u,int v,int w)
{
    b[++cnt].nxt=head[u];
    b[cnt].to=v;
    b[cnt].w=w;
    head[u]=cnt;
}
void make(int u,int v,int w)
{
    add(u,v,w);
    add(v,u,0);
}
queue<int> q;
bool bfs()
{
    while(!q.empty())q.pop();
    for(int i=1;i<=T;i++)    dep[i]=INF,cur[i]=head[i];
    q.push(xs);
    dep[xs]=1;
    int i,v;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        i=head[u];
        while(i)
        {
            v=b[i].to;
            if(dep[v]>dep[u]+1&&b[i].w>0)
            {
                dep[v]=dep[u]+1;
                q.push(v);
            }
            i=b[i].nxt;
        }
    }
    return dep[xt]!=INF;
}
int dfs(int u,int minn)
{
    if(u==xt)
    {
        ans+=minn;
        return minn;
    }
    int i=cur[u],v,tmp=minn,used=0;
    while(i)
    {
        cur[u]=i;
        v=b[i].to;
        if(b[i].w>0&&dep[v]==dep[u]+1)
        {
            tmp=dfs(v,min(minn-used,b[i].w));
            if(tmp>0)
            {
                used+=tmp;
                b[i].w-=tmp;
                b[i^1].w+=tmp;
                if(used==minn)
                    break;
            }
        }
        i=b[i].nxt;
    }
    return used;
}
void Dinic()
{
    while(bfs())
    {
        dfs(xs,INF);
    }
}
int main()
{
    scanf("%d",&n);s=n+1,t=s+1,S=t+1,T=S+1;
    for(int i=1,v;i<=n;i++)
    {
        make(s,i,INF);
        make(i,t,INF);
        scanf("%d",&m);
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&v);
            in[v]++;
            out[i]++;
            make(i,v,INF-1);
        }
    }
    for(int i=1;i<=t;i++)
    {
        if(in[i]>out[i])
            make(S,i,in[i]-out[i]);
        else if(in[i]<out[i])
            make(i,T,out[i]-in[i]);
    }
    make(t,s,INF);
    xs=S,xt=T;
    Dinic();
    int tmp=b[cnt].w;
    ans=0;b[cnt].w=b[cnt^1].w=0;
    xs=t,xt=s;
    Dinic();
    printf("%d\n",tmp-ans);
    return 0;
}
/*
8
1 3
1 7
2 4 5
1 8
1 8
0
2 6 5
0
*/

 

\(9:30\)

YPJ叫我们回宿舍楼铺床,还有 \(30mins\) 熄灯,路上:
“你们只有 \(10mins\) 铺床 \(10mins\) 洗漱。”
“那就是还有 \(10mins\) 打游戏。”
“你立刻退役还有 \(2\) 年时间打游戏。”

回宿舍铺床后还剩 \(15mins\)。上个厕所发现厕所积水漫过脚后跟,一只袜子没了QWQ。

随便刷牙洗脸后只剩 \(5mins\) 了,而此时大部分同学才刚刚铺完床。然而最早洗漱的我也没时间洗脚。

对哦,宿舍楼漏水&淋浴的水速高达 \(15滴/s\)

伴随着筷子敲铁碗要饭似的声音,熄灯了。

刺激

忽然衡中教练来收手机,然后YPJ来收手机,不过好像没真收?

吓得我把手机塞到了床垫下 没有的事

睡上铺,晚上被空调吹到腿抽筋,冷,很晚才睡着。

在衡水的第一天朴实无华的结束了。

SDFZ的食堂宿舍机房配置质量上比HZ强。

另一个发现是,没有发现HZ人放学路上看书(反倒是SDFZ某些卷王在这么干),但是他们几乎没有见他们说闲话,宿舍里也只有我们SDFZ的两间有声音,吃饭和洗漱几乎都是十几分钟解决,之后立刻六亲不认地消失。


Day 1

\(5:30\) 起床早自习,在大家都神志不清的时候放了一首电音。

你别说还开心了点(

去码,不知道为啥博客园登不上,于是随便写了写后去吃饭。

然后一直码到 \(9:00\) (QAQ我滥用 \(LateX\)

讲卡特兰数&范德蒙恒等式&二项式反演,衡中巨佬们纷纷AK,HKHcutest一旁懵逼。

感觉数学比网络流难多了QWQ为啥他们听得懂数学听不懂网络流(当时候我网络流自学的QWQ)

不过上课时困炸了什么也没学到而且还在溜号。

算了还是先去写完负圈然后写上下界网络流去了,数学自己看看OI-WIKI算了。

消圈

题解
这道题有点迷。。。

基本思想是,对于负数费用的边,将其强制满流,即下界等于上界。

讲师:image

对于这种情况,负边对答案无影响,但是会计入,所以这个算法有时候会假。

但是实际上并不会假。

因为消圈算法中会反向建立一条 \(1->t\) 的边,流量1,费用8。在上下界网络流的超级源汇点中会流过,所以花费还是 \(0\)

代码
#include<bits/stdc++.h>
using namespace std;
const int N=4000,INF=0x7fffffff,M=150000;
int n,dis[N],m,s,t,head[N],cnt=1,cur[N],S,T,xs,xt,d[N],ans,cost;
bool inq[N],vis[N];
struct bian
{
    int nxt,to,w,c;
}b[M];
void add(int u,int v,int w,int c)
{
    b[++cnt].nxt=head[u];
    b[cnt].w=w;
    b[cnt].c=c;
    b[cnt].to=v;
    head[u]=cnt;
}
void make(int u,int v,int w,int c)
{
    add(u,v,w,c);
    add(v,u,0,-c);
}
queue <int> q;
bool SPFA()
{
    for(int i=1;i<=T;i++)
    {
        dis[i]=INF;
        cur[i]=head[i];
    }
    inq[xs]=1;
    q.push(xs);
    dis[xs]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        inq[u]=0;
        int i=head[u],v;
        while(i!=0)
        {
            v=b[i].to;
            if(b[i].w>0&&b[i].c+dis[u]<dis[v])
            {
                dis[v]=dis[u]+b[i].c;
                if(!inq[v])
                {
                    inq[v]=true;
                    q.push(v);
                }
            }
            i=b[i].nxt;
        }
    }
    return dis[xt]!=INF;
}
int dfs(int u,int minn)
{
    if(u==xt)
    {
        vis[xt]=1;
        ans+=minn;
        return minn;
    }
    int i=cur[u],v,tmp=minn,used=0;
    vis[u]=1;
    while(i)
    {
        cur[u]=i;
        v=b[i].to;
        if(b[i].w>0&&dis[v]==dis[u]+b[i].c&&(vis[v]==0||v==xt))
        {
            tmp=dfs(v,min(minn-used,b[i].w));
            if(tmp>0)
            {
                cost+=b[i].c*tmp;
                used+=tmp;
                b[i].w-=tmp;
                b[i^1].w+=tmp;
                if(used==minn)
                    break;
            }
        }
        i=b[i].nxt;
    }
    return used;
}
void Dinic()
{
    while(SPFA())
    {
        vis[xt]=1;
        while(vis[xt])
        {
            memset(vis,0,sizeof(vis));
            dfs(xs,INF);
        }
    }
    return;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);S=n+1;T=S+1;
    for(int i=1,u,v,w,c;i<=m;i++)
    {
        scanf("%d%d%d%d",&u,&v,&w,&c);
        if(c>=0)
        {
            make(u,v,w,c);
        }
        else
        {
            make(v,u,w,-c);
            d[u]-=w;
            d[v]+=w;
            cost+=w*c;
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(d[i]>0)
            make(S,i,d[i],0);
        else
            make(i,T,-d[i],0);
    }
    xs=S,xt=T;
    make(t,s,INF,0);
    Dinic();
    ans=0;
    xs=s,xt=t;
    Dinic();
    printf("%d %d\n",ans,cost);
    return 0;
}

 

中午搭蚊帐耗时50mins还用塑料袋卷了两条绳子QAQ。

写一下午无限之环未果,晚上继续然后吴孟周巨佬来讲了树形DP,听讲效率还可但不想写代码。

然后继续写无限之环。

晚上回去晚了,超级快的速度洗了冷水澡,然后睡觉去了。

打开手机手电筒铺床,刚说了一句闲话,忽然听见YPJ说:

一人玩一个手机?都交上来。

害怕。

衡水的完整一天结束了。

我发现HZ食堂是真的好。。。
虽然价格上跟SDFZ差不多,但是

好吃

见到直接用肉填满的手抓饼直接泪奔。

导致伙食费翻倍虽然伙食费就很多

顺带一提YPJ饭卡名字是张紫琪xswl。
虽然我的饭卡是坤坤。


Day 2

\(5:30\) 起了,放的还是昨天那首。

但我觉得每天换一首我可能就会更开心了。

上下铺梯子巨硌,每天上下床都做高危险动作。

上午继续码无限之环。

真成无限之环了艹

几乎Debug完以后,发现有一些情况当时将这个题没有说,而我傻傻地直接按照讲得建图写了没多想。

发现问题,瞬间丧失全部斗志开始颓浮生物语。

不得不说树姐姐写得真是好。

开始写了一点树的重心写了一半写不下去,还是想改出来无限之环。

改了一会又开始颓浮生。

颓完一篇以后去找A神详细分析了一下无限之环还有没有补救余地,发现只能进行重构代码级别的大改。

丧失斗志,继续颓浮生。

然后就被YPJ看到了。

教育后恢复部分动力全力冲了一道星际竞速。

爆蛋后再次丧失全部斗志。

然后吃饭睡觉打豆豆。

下午来的时候是1道题没调出来,1道题没写完,还有1道题要重构的烂摊子。

还好包里翻出来的太原拿过来的茶pai短暂安抚了我一下。

上课,构造题,听课还可以,最后一点点有点懵。

衡中发西瓜了开开心心去吃。(A神差一点就第一次吃的比我快了)

(好想和A神天天AA吃饭)

然后打算写一下HZ游记进入状态,然后输入法挂了。

然后颓起了知乎又被YPJ看到了。

重启,写游记。

先调一个星际竞速。

2 hours later.

我TMD调了TMD两个小时的TMD的星际TMD竞速,最后发现TMD命名空间和TMD全局变量TMD定义TMD重复???

讲真感觉虽然class写出来很难看而命名空间比较间接但是class难出锅。
提交记录刷屏了

18:48,写一点博客进入状态然后写几个构造题吧。

如果有HZ人看到这里,可不可以告诉我一下,去哪里买到你们的校服QAQ

一些杂事:

  1. 以目前的情况看,再过一周就可以吃全衡中食堂了。(真不愧是收集控)
  2. 这几天一直在机房教学楼、宿舍和食堂游走,其他地方完全不认识,天黑一点都会迷路。。。想找份HZ地图看看。
  3. 从太原带来的饮料喝光了,缺乏补给。
  4. 表情包不在这里,感觉博客写起来没那味儿。
  5. 博客园每天早晨都莫名其妙无法登录。
  6. 宿舍墙上掉粉,已经毁了一身衣服了QWQ。现在睡觉小心翼翼。
  7. 感觉确实蚊帐没卵用。仅有的作用是让你感觉睡在晶莹剔透的水晶棺材里更梦幻了。

Cyber_Tree:配上你的粉色被子更梦幻
HKHcutest:是的呢还有我红嫩嫩的枕头和粉嫩嫩的少女心呢~

于是Cyber_Tree吐了
事实证明别人恶心你时最好的反击方法就是比他更恶心

就到这里吧~,写几道构造题去了!

写了一道游戏

题解
此题考虑完全图的三元环个数,取最大的小于等于 $n$ 的完全图,然后枚举新建一个点向 $n-1$ 个点、$n-2$ 个点、$n-3$ 个点、……、$2$ 个点连边。 最后剩下的点(寥寥无几)通过不断新建一个点向1、2连边解决。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1100000;
inline int read() {
    int z = 0, w = 1;
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == \'-\')
            w = -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        z = z * 10 + ch - \'0\';
        ch = getchar();
    }
    return z * w;
}
int n, m, tot;
bool b[1000][1000];
int main() {
    n = read();
    for (int i = 3; i <= 0x7fffffff; i++) {
        if (i * (i - 1) * (i - 2) / 6 > n)
            break;
        m = i;
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 2; j <= m; j++)
            b[i][j] = 1;
    }
    n -= m * (m - 1) * (m - 2) / 6;
    for (int i = m - 1; i >= 2; i--) {
        if (n >= (i * (i - 1) / 2)) {
            n -= i * (i - 1) / 2;
            m++;
            for (int j = 1; j <= i; j++) {
                b[j][m] = 1;
                b[m][j] = 1;
            }
        }
    }
    while (n) {
        m++;
        b[2][m] = b[m][1] = b[1][m] = b[m][2] = 1;
        n--;
    }
    printf("%d\n", m);
    for (int i = 1; i <= m; i++) {
        for (int j = i + 1; j <= m; j++) {
            printf("%d ", b[i][j]);
        }
        puts("");
    }
    return 0;
}

 

Errich-Tac-Toe
时,差不多码完的时候,忽然HZ教练走进来说可以开始颓废了。
全SDFZ人都感到很魔幻

全HZ人好像也感到很魔幻
反正就是我和Cyber_Tree开开心心去踢球了,其他人去打篮球了,HZ人打羽毛球和乒乓球的居多,但是大部分人还留在机房。
踢球的时候意外在衡中操场发现了青蛙!

我印象里青蛙大概有我手那么大,然而我们见到青蛙大约只有长5厘米宽2~3厘米这样子,但是其他的所有方面都和我印象里的青蛙一模一样。

和青蛙一起做了10个蛙跳

回宿舍,大家都要冲冷水澡(因为没有热水),全宿舍除了我和星光0000都跑到别的空宿舍用洗澡间了。

于是我找到SpadeA261的房间暴力进入

回宿舍,自己放了每天早晨听到的电音

睡觉。

讲真和我印象里的河北不一样,比如说在衡水第一次见到真正的浓雾(不是雾霾,货真价实的水汽)。还第一次见到青蛙~
生态要比SDFZ好很多。
另外,衡水的蝉超级吵闹,但是偶尔有一阵子所有的蝉全停下来,或者忽然安静许多,很有意思。

顺带一提,发现衡水留在机房的人集体褪三国杀、音游。但平常没见他们玩过。

附集训作息时间表
上午
5:35起床洗漱
6:00到机房
6:40去食堂吃饭
7:00到机房
12:10去食堂吃饭

下午
1:50到机房被
6:00去食堂吃饭
6:30到机房
9:40回宿舍
10点熄灯睡觉


Day 3

起床,来机房写博客,吃饭 。

\(5:30\) 起床以后迟到了一会才到了机房,然而所有衡水人早已到达,我在机房也从来没见过有衡水人上OI以外的网站。

然而我却会颓知乎

也许HZ有人水洛谷,那我就看不出来了。

想到一个情景:

两个人坐在衡中路边,凝视着人来人往:
“你是不是觉得衡中是一台打机器,这里每个人都是零件,遵循着机械的规则,没有人有自己的自由。”
“不,我是在想,衡中女生的小腿好粗。”

Errich-Tac-Toe题解
把格子按照 $(i+j)%3$ 分类,发现如果有两类格子,同一类颜色相同,这两类颜色不同,那么必定平局( 能想出这个东西的人真是个人才),然后做出3种方案即可,注意选择3种方案时,更改的格子不要重复,要满足总和为 $k$ 。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=500;
inline int read()
{
    int z=0,w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==\'-\')w=-1;ch=getchar();}
    while(isdigit(ch)){z=z*10+ch-\'0\';ch=getchar();}
    return z*w;
}
int T,n,ans[3],opt;
char s[N][N];
int main()
{
    T=read();
    while(T--)
    {
        ans[0]=ans[1]=ans[2];
        n=read();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s[i]+1);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(!((i+j)%3))
                {
                    if(s[i][j]==\'X\')
                    {
                        ans[0]++;
                    }
                    else if(s[i][j]==\'O\')
                    {
                        ans[2]++;
                    }
                }
                else if((i+j)%3==1)
                {
                    if(s[i][j]==\'O\')
                    {
                        ans[0]++;
                    }
                    else if(s[i][j]==\'X\')
                    {
                        ans[1]++;
                    }
                }
                else if((i+j)%3==2)
                {
                    if(s[i][j]==\'O\')
                    {
                        ans[1]++;
                    }
                    else if(s[i][j]==\'X\')
                    {
                        ans[2]++;
                    }
                }
            }
        }
        if(ans[0]<=ans[2]&&ans[0]<=ans[1])
        {
            opt=1;
        }
        if(ans[1]<=ans[0]&&ans[1]<=ans[2])
        {
            opt=2;
        }
        if(ans[2]<=ans[1]&&ans[2]<=ans[0])
        {
            opt=3;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(!((i+j)%3))
                {
                    switch(opt)
                    {
                        case 1:
                            putchar(s[i][j]==\'.\'?\'.\':\'O\');
                            break;
                        case 2:
                            printf("%c",s[i][j]);
                            break;
                        case 3:
                            putchar(s[i][j]==\'.\'?\'.\':\'X\');
                            break;
                    }
                }
                else if((i+j)%3==1)
                {
                    switch(opt)
                    {
                        case 1:
                            putchar(s[i][j]==\'.\'?\'.\':\'X\');
                            break;
                        case 2:
                            putchar(s[i][j]==\'.\'?\'.\':\'O\');
                            break;
                        case 3:
                            printf("%c",s[i][j]);
                            break;
                    }
                }
                else if((i+j)%3==2)
                {
                    switch(opt)
                    {
                        case 1:
                            printf("%c",s[i][j]);
                            break;
                        case 2:
                            putchar(s[i][j]==\'.\'?\'.\':\'X\');
                            break;
                        case 3:
                            putchar(s[i][j]==\'.\'?\'.\':\'O\');
                            break;
                    }
                }
            }
            puts("");
        }
    }
    return 0;
}
/*
3
3
.O.
OOO
.O.
6
XXXOOO
XXXOOO
XX..OO
OO..XX
OOOXXX
OOOXXX
5
.OOO.
OXXXO
OXXXO
OXXXO
.OOO.

*/

 


Mine Sweeper II

Mine Sweeper II题解
不难意会到,可以把B改成和A一模一样或者完全相反,取步数小的。 给个证明完全相反的权值等价于正常权值?
代码
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1100;
    int n,m,ans[2];
    char a[N][N],b[N][N];
    int c(char x)
    {
        return x==\'X\'?\'.\':\'X\';
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",a[i]+1);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%s",b[i]+1);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(a[i][j]!=b[i][j])
                    ans[0]++;
                else
                    ans[1]++;
            }
        }
        if(ans[0]<ans[1])
        {
            for(int i=1;i<=n;i++)
            {
                printf("%s\n",a[i]+1);
            }
        }
        else
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    putchar(c(a[i][j]));
                }
                puts("");
            }
        }
        return 0;
    }
    /*
    2 4
    X..X
    X.X.
    X.X.
    .X..
    X.XX
    .X..
    */

 

上午 \(8:30-12:00\)讲期望DP,几乎懵逼,只立刻学会了打表找决策单调性。

先写完构造再说。

写一下午题,效率略差。

晚上听巨佬WMZ讲课,数位DP,虽然学过,但非常懵逼。

我好差呀。

吴孟周刷博客太刺激了

OI至高算法,只要XIN队算法打满,保证所有比赛 rk1,碾爆标程,让对手望尘莫及。

为 XIN队 献上 H1!
圣经永不过时


Day 4

阅读量竟然已经130了,略开心。
但是别光看不点赞啊!

博客就抖个机灵别当真。

昨天晚上做了一个有极为宏大历史背景的震撼的梦,起来时恍如隔世。

早晨去搬电脑了,希望这回机子能收到广播。(换的第三台电脑)

上午考试,T1一下大意忘了单个循环节内一数字不会重复出现,写了一个带线段树可以做能重复出现的情况。

本来是怕调不出来了,忽然仿佛想到FAKE佬的教诲:“你想正式考试不用数据结构吗?不想平常模拟赛就得写数据结构。写过一次你就有信心了。”

然后我花20mins才搞出了一颗单点修改区间查询线段树。

不过真的是我第一次在考场上用出数据结构~Cheers!!!

虽然只过了T1,rk9 ,但实现了从无到有的突破,开心。

T1代码
#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) (x&(-x))
using namespace std;
inline int read()
{
    int s=0,w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==\'-\')w=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-\'0\';ch=getchar();}
    return s*w;
}
inline ll readll()
{
    ll s=0;int w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==\'-\')w=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-\'0\';ch=getchar();}
    return s*w;
}
int _max(int a,int b)
{
    return a>b?a:b;
}
ll _maxll(ll a,ll b)
{
    return a>b?a:b;
}
int _min(int a,int b)
{
    return a<b?a:b;
}
const int N=1100000,M=200;
const ll INF=0x7fffffffffffffff;
ll n,ans,num[M],l,r,len,L,R,f[N],num2[M];
int t1,A,B,C,D,s[N],pre[M],zhan[N],top;
struct xds
{
    int l,r;
    ll mx;
}t[N<<2];
void up(int p)
{
    t[p].mx=_maxll(t[p*2].mx,t[p*2+1].mx);
}
ll query(int p,int x)
{
    if(t[p].r<=x)
    {
        return t[p].mx;
    }
    ll res=0;
    if(t[p*2].l<=x)
        res=_maxll(res,query(p*2,x));
    if(t[p*2+1].l<=x)
        res=_maxll(res,query(p*2+1,x));
    up(p);
    return res;
}
void change(int p,int x,ll v)
{
    if(t[p].l==x&&t[p].r==x)
    {
        t[p].mx=v;
        return;
    }
    if(t[p*2].r>=x)
        change(p*2,x,v);
    else
        change(p*2+1,x,v);
    up(p);
}
void build(int p,int l,int r)
{
    t[p].l=l;
    t[p].r=r;
    if(l==r)
    {
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    up(p);
}
int main()
{
    //freopen("in.in","r",stdin);
    //freopen("out1.out","w",stdout);
    n=readll();
    t1=read();A=read();B=read();C=read();D=read();
    s[1]=t1;pre[t1]=1;
    for(int i=2;i<=n;i++)
    {
        s[i]=A*s[i-1]*s[i-1]+B*s[i-1]+C;
        s[i]=s[i]%D;
        if(!pre[s[i]])
        {
            pre[s[i]]=i;
        }
        else
        {
            L=l=pre[s[i]];
            r=i-1;
            len=r-l+1;
            break;
        }
    }
    if(l!=0&&r!=0)
    {
        for(int i=l;i<=r;i++)
        {
            num[s[i]]++;
        }
        for(int i=2,tr;i<=len;i++)
        {
            tr=r+(i-2)*len;
            for(int j=1;j<=len;j++)
            {
                s[tr+j]=s[l-1+j];
                if(tr+j>n)
                    break;
            }
        }
        R=r+(len-1)*len;
        if(R>n)
            R=n;
        for(int i=0;i<D;i++)
        {
            num[i]*=((n-R)-(n-R)%len)/len;
        }
        for(int i=0;i<(n-R)%len;i++)
        {
            num2[s[l+i]]++;
        }
    }
    if(!R)
        R=n;
    zhan[0]=-0x7fffffff;
    build(1,1,R);
    for(int i=1;i<=R;i++)
    {
        if(s[i]>=zhan[top])
        {
            zhan[++top]=s[i];
            f[i]=top;
            change(1,top,num[s[i]]);
            //printf("%lld ",f[i]);
            f[i]+=query(1,top)+num2[s[i]];
            ans=_maxll(ans,f[i]);
        }
        else
        {
            int le=1,ri=top,mid;
            while(le<ri)
            {
                mid=(le+ri)/2;
                if(zhan[mid]<=s[i])
                {
                    le=mid+1;
                }
                else
                {
                    ri=mid;
                }
            }
            change(1,le,0);
            f[i]=le;
            //printf("%lld ",f[i]);
            zhan[le]=s[i];
            change(1,le,num[s[i]]);
            f[i]+=query(1,le)+num2[s[i]];
            ans=_maxll(ans,f[i]);
        }
    }
    printf("%lld\n",ans);
    return 0;
}
/*
10
1 1 3 5 37
*/

 

下午有点烂。差不多是4小时抄题解改两题。

T2题解
分层图同余最短路,我学了个半调子,大意就是背包通过同余将极大的容积变小(同余最小物品的体积),SPFA优化DP。(STD里最后的一种算法不会) 顺便一膜SZS巨佬。
T2代码
#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
const int N=60;
int n,m,l,c,v[N],pos,minn=0x3f3f3f3f3f3f3f3f;
int dis[10005],cnt[10005];
queue<int>q;
bool in[10005];
inline ll readll()
{
    ll s=0;int w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==\'-\')w=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-\'0\';ch=getchar();}
    return s*w;
}
void SPFA(){
    memset(dis,0x3f,sizeof(dis));
    memset(cnt,0x3f,sizeof(cnt));
    dis[0]=cnt[0]=0;
    in[0]=1;
    q.push(0);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        in[x]=0;
        for(int i=1;i<=n;++i)
        {
            int y=(x+v[i])%minn;
            if(v[i]>=l&&cnt[x]>=c) break;
            if(dis[y]>dis[x]+v[i])
            {
                dis[y]=dis[x]+v[i];
                if(v[i]>=l) 
                   cnt[y]=cnt[x]+1;
                if(!in[y])
                    q.push(y),in[y]=1;
            }
            else if(dis[y]==dis[x]+v[i])
            {
                if(cnt[y]>cnt[x]+(v[i]>l))
                {
                    cnt[y]=cnt[x]+1;
                    if(!in[y])
                    {
                        q.push(y);
                        in[y]=1;
                    }
                }
            }
        }
    }
}
signed main(){
    n=readll();m=readll();
    for(int i=1;i<=n;++i)
    {
        v[i]=readll();
        minn=min(minn,v[i]);
    }
    l=readll();
    c=readll();
    sort(v+1,v+n+1);
    SPFA();
    for(int i=1,x;i<=m;++i){
        scanf("%lld",&x);
        if(dis[x%minn]<=x) puts("Yes");
        else puts("No");
    }
    return 0;
}

 

T3题解
统计黑点的贡献。线段树DFS序上维护子树。![image](https://img2020.cnblogs.com/blog/2115448/202108/2115448-20210803213620486-1237235223.png)
T3代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=1e5+5;
int n,m,w[MAXN];
bool vis[MAXN];
int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0;
void add(int u,int v){
    ++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
}
int in[MAXN],out[MAXN],fa[MAXN],dfn=0;
void dfs(int x){
    in[x]=++dfn;
    for(int i=pre[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa[x]) continue;
        fa[y]=x;
        dfs(y);
    }
    out[x]=dfn;
}
int tr[MAXN<<2],laz[MAXN<<2];
void down(int k){
    tr[k<<1]=max(tr[k<<1],laz[k]);
    tr[k<<1|1]=max(tr[k<<1|1],laz[k]);
    laz[k<<1]=max(laz[k<<1],laz[k]);
    laz[k<<1|1]=max(laz[k<<1|1],laz[k]);
    laz[k]=0;
}
void update(int k,int l,int r,int opl,int opr,int val){
    if(opl<=l&&r<=opr){
        tr[k]=max(tr[k],val);
        laz[k]=max(laz[k],val);
        return ;
    }
    if(laz[k]) down(k);
    int mid=(l+r)>>1;
    if(opl<=mid) update(k<<1,l,mid,opl,opr,val);
    if(opr>mid) update(k<<1|1,mid+1,r,opl,opr,val);
    tr[k]=max(tr[k<<1],tr[k<<1|1]);
}
int query(int k,int l,int r,int opt){
    if(l==r) return tr[k];
    if(laz[k]) down(k);
    int mid=(l+r)>>1;
    if(opt<=mid) return query(k<<1,l,mid,opt);
    else return query(k<<1|1,mid+1,r,opt);
}
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%lld",&w[i]);
    }
    for(int i=1,u,v;i<n;++i){
        scanf("%lld%lld",&u,&v);
        add(u,v),add(v,u);
    }
    dfs(1),vis[0]=1;
    for(int i=1;i<=m;++i){
        char opt[10];
        int v,ans;
        scanf("%s%lld",opt,&v);
        if(opt[0]==\'M\'){
            update(1,1,n,in[v],out[v],w[v]);
            vis[v]=1;
            while(vis[fa[v]]!=1){
                update(1,1,n,in[fa[v]],in[v]-1,w[fa[v]]);
                update(1,1,n,out[v]+1,out[fa[v]],w[fa[v]]);
                v=fa[v];
            }
        }else{
            ans=query(1,1,n,in[v]);
            if(!ans) ans=-1;
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

巨佬高俊垚终于回我了,开心。

另外:
HZ的小伙伴们来找我说几句话吧,每天穿着一个非常亮&显眼的橘色衣服的,非常颓废的就是QWQ。

晚上可以听AC自动机或字符串杂题,本来想复习AC自动机,但是大家都去听了杂题,于是我就也跟着去了,结果啥也不会听懂率小于1%。

还有:

你们怎么能把我第一段的别的收获说成是妹子呢???明明是难得正经的一点感悟。

真要能在HZ收获妹子还至于在SDFZ混成酱紫

再补一段。

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊刚刚往前面一转悠发现好几台机子背景是一个蓝不拉几的星球坠落背景。

社死现场。

社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了杜死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了社死了。

刚刚小眼告诉我这件事的时候我听成了吴巨佬看我博客了。

直接害怕。

我发神经千万别让神犇看见。

我觉得我游记里关于HZ的内容应该有许多和事实不一样的地方
你们不可以评论一下指出来吗QAQ


Day 5

昨天晚上不知道哪个憨憨开了空调强风,于是正对风口的发烧了。

但是上午还是去看了看题,感觉T1折半搜索,没写就熬不住了。

老师带我去医务室,还问有没有做核酸。

其实到衡水集训然后还发烧然后做核酸这也没几个人经历过吧。

但最后并没有做核酸。

躺着养病。

下午感觉好点,测温比上午高1℃,39多。

晚上40℃。
巨佬Rings给我带了中午的饭,感动。

Cyber_tree带了晚饭,感动。

教练也带了晚饭QAQ,还是很感动。

爸妈直接往衡水赶过来了,开心,很温暖,感觉跟他们打电话时候那么不耐烦好对不起……

一年级的时候,家住顶楼,屋顶漏水,下雨天直接水打进来,一屋子没有床,拿铁架子支起来睡觉,一屋子只有一个塑料管水龙头。

然后我发烧了7天,最高两天40摄氏度。

最严重的那一天,晚上我忽然醒过来,说我梦到在机场,有很多飞机,周围的人都穿着黑(还是白衣服 忘了)衣服,互相不说一句话,忙着上飞机。

我那时没坐过一次飞机,因此一直很想坐飞机。我说我要上飞机啦。听见我妈说

爸爸妈妈还在这,你不要去坐飞机。

我半睡半醒的时候,听见她一直在说,一直听见几十次。

分类:

技术点:

相关文章: