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个小时就可以写完,所以要多想。
posted @ 2019-06-01 14:32  fcwww  阅读(1136)  评论(1编辑  收藏  举报