THUPC2019/CTS2019/APIO2019/PKUSC2019游记
THUPC2019/CTS2019/APIO2019/PKUSC2019游记
5.10
中铺,火车好晃啊
5.11
打了THUPC2019的练习赛,华容道好评(四个小兵,杠鸭!)
5.12
打了THUPC2019
开场爆了好几发D,然后不想写,丢给ZCY,cerr居然wa了好多发
然后ZCY看出B是sb题,我们俩不想写,丢给ZCY
然后gmy和我分别写了M和J两个签到题,三人开始分别开C,I,L
ZCY丢给我一个\(O(m)\)的式子让我优化,我推了推之后发现k才20
你容斥是\(O(k^2)\)的又不是\(O(2^k)\)的你优化这个干嘛
然后我写容斥部分,他写组合数部分,交上去,WA ???
woc这个模数太小了可能没逆元啊,然后改改改改改,交上去,过了
此时gmy的I已经会了,但是我们俩又没人想写,依然丢给ZCY
写完一直WA,交暴力也WA
我们都在喷卡精的时候交了一发puts("nan");
然后过了,良心SPJ,最后rk36滚粗了
然后是讲评环节,广告俩小时,讲题???不会的还是不会
高调三人南,点了zcy的大三元,体验被飞的快感
晚上到宾馆才发现I题读入搞错了,我是傻逼
回去之后改了L和K。
5.13
在食堂里看到了rvalue,刚想打招呼就不见了QAQ,还好在考场旁又遇到了
然后打了CTS2019Day 1
玩题答3h+俩暴力
出来一看分数还行
orz \(\color{red}{\mathrm{Itst}}\) 切t2
5.14
打了CTS2019Day 2
写了30+10+0
一看成绩10+10+0
傻逼了,打铁滚粗了,凸包都能写错。
原因大概是我把左下角那个基准点也丢进去排序了吧
5.15
这都能领奖,还是个ag,不亏
吃顿神仙火锅平均一人90rmb,吓尿了
5.16
lzh来了,气氛突然变得?了起来
然后我被拉入lol坑
5.17
上午讲厉害东西完全听不懂,直接导致我下午去都没去。
5.18
打了APIO2019,自闭了
开场写完仨暴力,开始搞t1(device),想了想好像挺傻逼的。
就是拆环做区间覆盖就行了。
我写了5k特判,然后因为有四个模数(A,B,B+1,A/gcd(A,B+1)),调不出来了。
最后20+43+60滚粗了。
出来一问大家都203,txc聚聚更是提前2小时ak离场
那我垫底稳了啊
5.19
上午又讲厉害东西,不过感觉比前天那个好玩?
晚上颁奖,我居然还有块Cu,不亏不亏
这下noi赛事的三个牌牌都齐了,就剩noi2019去打铁了(雾)
5.20
忘记干啥了
5.21 ~ 5.24
复习
5.25
全世界只有我在北京还没去tho,甚至连live party都去不上.jpg
下午打了PKUSC2019Day1
看t1,好像是个逆序对傻逼题
看t2,好像是个厉害题
看t3,好像还是个傻逼题
先写t3,对每个点搞出来61个数然后判加和是否能组成就行了吧
搞了个bitset优化背包,拿了60分 感觉再卡卡常就能过了(flg)
然后写t1,写个主席树上去就过了,此时不过1h,感觉很稳(flg)
开始刚t3,写了这么个乱搞:
- 当可用数字个数大于22时直接视为可行 (22是二分出来的)
跑得飞快啊,直接2.几s
然后又yy出一个能使常数减半的做法,不过需要手写bitset控制位数= =
于是我就打开自带的mingw开始看里面的bitset
看了一个小时左右,突然意识到自己在考试,好像浪费一个小时不是很值(很傻逼)
看看t2吧,想了好长时间才发现可以枚举一个点
枚举一个点,把小于的视为0,大于的视为2,0022之间不影响。
然后状态数就非常少了,写了一发卡了卡常就过了。
回去卡t3,加了好多玄学优化(到最后也没手写bitset)
突然发现最后一个点艹过去了(1992ms),然后第一个点wa了???不过还好取最高还有93分..
把第一个点特判掉之后就过不去最后一个点了(20xxms),感觉评测机上下浮动很正常,那我多交几发就过了(flg)。
然后32发交到最后,流局了
提前出考场假装ak还行
问群里大佬,好多都提前2h ak啊
这个t3只要在trie树上做就好了啊,有用的点一共n个,按深度存log个bitset就行了,wtcl这都想不到。
明天继续加油QAQ
5.26
看题,woc三个树题,要爆零了
看t1,写完n^2的dp之后看了看链的做法,然后就会了正解
一开始写了个线段树合并然后发现并不能标记下传时新建节点,此时1h过去了QAQ
想着换成线段树启发式合并或者splay启发式合并能好写一点,先去看t2t3
看t2,只会8分
看t3,看了好久才看明白弦图是啥玩意,暴力不会打,告辞
只能去写t1啦,这个t1好像可以每次只维护子树内有限制的颜色集合,这样标记下传时不用新建节点比较妙,写一半发现我的做法在求点积的时候需要先乘再除,然后乘0就GG了,判掉乘0之后已经又过了2h。
交一发,AcAcWaTle ,这啥玩意啊
发现m的范围好像不是2e5是1e9啊,那我空间还得再开大一点..诶怎么就mle了。
在想要不要换成splay启发式合并来优化空间和时间(此时已经把一开始的线段树合并扔掉了QAQ)
想了想还是算了,打暴力吧,这题过的人应该不多(flg)
然后玩t2二叉树的分..,写了个暴力发现这个\(m=\lceil n/4\rceil\),求出\(m\)之后直接搜就搜出来答案了。
那后面的点应该也是这样做吧,就开始猜这个\(m\)是什么,然后没猜出来凉了
最后0.5h刚t3,感觉应该能找找规律,然后发现线弦图一定不存在长度大于等于4的环,写写写暴力,没调出来,滚了。
出来问成绩,好多大佬说今天比昨天简单???
47+49+0=96,被高一的ysy和gmy吊打50分,怎么人均切t1t2啊QAQ
然后又听说有好多人600... 我今天成功被区分了
听大佬讲题,t1做法都一样只是我调不出来别人能调出来,t2那个m其实就是链覆盖(叶子个数/2), t3注意到结论之后变成树上dp,每次乘一个两项的多项式,用分治fft即可。
5.27
颁奖颁奖
拿了个二等跑路
给高二的奖好少啊
初三和高二的一等奖线大概差了200分
在火车上写d2t1的线段树合并,甚至比启发式合并好写??完全不用处理乘0的情况
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
#define mod 998244353
#define N 400050
#define M 20000050
#define db(x) cerr<<#x<<" = "<<x<<endl
#define fov(i,x) for(i=0;i<(int)x.size();i++)
ll qp(ll x,ll y=mod-2) {ll re=1;for(;y;y>>=1,x=x*x%mod)if(y&1)re=re*x%mod; return re;}
int head[N],to[N],nxt[N],cnt,n,m,K;
int ls[M],rs[M],tot,siz[M];
int sum[M],tag1[M],tag2[M];
vector<int>V[N];
struct node {
int rt;
ll O,s;
void gs() {
s=(sum[rt]+(m-siz[rt])*O)%mod;
}
}tr[N];
node X,Y;
inline void add(int u,int v) {to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;}
inline void giv1(ll v,int p) {
if(!p)return ;
sum[p]=sum[p]*v%mod; tag1[p]=tag1[p]*v%mod; tag2[p]=tag2[p]*v%mod;
}
inline void giv2(ll v,int p) {
if(!p)return ;
sum[p]=(sum[p]+siz[p]*v)%mod; tag2[p]=(tag2[p]+v)%mod;
}
inline void pushdown(int p) {
if(tag1[p]!=1||tag2[p]) {
giv1(tag1[p],ls[p]);
giv2(tag2[p],ls[p]);
giv1(tag1[p],rs[p]);
giv2(tag2[p],rs[p]);
tag1[p]=1; tag2[p]=0;
}
}
inline void pushup(int p) {
sum[p]=(sum[ls[p]]+sum[rs[p]])%mod;
siz[p]=siz[ls[p]]+siz[rs[p]];
}
void update(int l,int r,int x,int &p) {
if(!p) { p=++tot; tag1[p]=1; siz[p]=1; }
if(l==r) { sum[p]=0; return ;}
int mid=(l+r)>>1; pushdown(p);
if(x<=mid) update(l,mid,x,ls[p]);
else update(mid+1,r,x,rs[p]);
pushup(p);
}
int merge(int l,int r,int x,int y) {
if(!x&&!y) return 0;
if(!y) {
giv1(Y.O,x);
return x;
}
if(!x) {
giv1(X.O,y);
return y;
}
if(l==r) {
sum[x]=(sum[x]*sum[y])%mod;
return x;
}
int mid=(l+r)>>1;
pushdown(x); pushdown(y);
ls[x]=merge(l,mid,ls[x],ls[y]);
rs[x]=merge(mid+1,r,rs[x],rs[y]);
pushup(x);
return x;
}
void dfs(int x,int y) {
int i;
tr[x].O=1;
fov(i,V[x]) update(1,m,V[x][i],tr[x].rt);
for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
dfs(to[i],x);
X=tr[x], Y=tr[to[i]];
tr[x].rt=merge(1,m,tr[x].rt,tr[to[i]].rt);
tr[x].O=tr[x].O*tr[to[i]].O%mod;
}
tr[x].gs();
ll s=tr[x].s;
if(x!=1) {
tr[x].O=(s-tr[x].O)%mod;
giv1(mod-1,tr[x].rt);
giv2(s,tr[x].rt);
}
}
int main() {
scanf("%d%d%d",&n,&m,&K);
int i,x,y;
for(i=1;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
for(i=1;i<=K;i++) scanf("%d%d",&x,&y),V[x].push_back(y);
dfs(1,0);
printf("%lld\n",(tr[1].s+mod)%mod);
}
总结
- 一定要看清输入格式
- 想到一个做法不要马上实现,要多想想细节,如果细节太多就换做法,不要怕浪费时间,一个5个小时的比赛,去除掉码量巨大的题,只需要2个小时就可以写完,所以要多想。