Day-3
据说今年HN试用自动丢收代码系统。如果真丢了就可以再次体验奥妙重重的Day3人工还原代码了。。
下午就跑去试机,真实模拟坐车晕车。
Day-2
被叫去搞心理辅导…??然后就出现了下面这幕
“你配合一下,下次就免死”
“OK”
……
“好,那接下来就是最后一局游戏~”
Day-1
考试差点翻车.jpg
下午做了两道51nod,晚上就去围观看猫和老鼠了
Day 0
要去爬岳麓山。去年NOIP前也说要爬岳麓山来着,只不过因为下雨咕咕咕了
话说有没有人能帮忙奶一下不考高精度啊qwqqq还有去年考了tarjan今年应该不考吧??
突然boshi告诉我逛公园的零环是要建立在于最短路不超过k的前提下的,我好像压根就没注意到…
爬完山腿废了…还有就是天气不错。回来的时候挤的公交,强行挤上去.jpg,体验极差。
早知道还不如坐地铁呢=~=
Day1
发现坐的大巴竟然又是纯电动,想到今年省选晕车,不免有点方。虽然最后没有晕车
T1好像可以st表+分治,担心会爆栈,另写了一个做法,拍了拍感觉没毛病
T2好像是同余系最短路,等等noip出这么难的题?后来别人告诉我直接上完全背包就可以了。。
T3肯定要二分,dp好像很麻烦,应该是贪心。然后证明了一条链的lca深度越深越好,就开始拿set乱搞。结果死活过不去大样例,最烦的是写不出暴力来拍,但是拍了一众特殊数据却稳如*。开始怀疑贪心策略有问题…下考前不久突然发现自己在两两配对的时候从大到小找,可能导致传上去的不是最优的。想着贪心策略可能本来就有问题,可能来不及改了,就检查去了。。
后来发现只要改了这个地方就可A了。wwwwwoc??早知道就改了……但是这个错误贪心可以完美地过掉链和菊花还有m=1等特殊数据。。不知道能不能多骗点分??
下午听说都是原题。嗯嗯?只有我一个人没有AK系列
Day2
可能是我最近睡的都挺早,导致昨晚躺床上1h没睡着。。翻车预警
一拿到题目发现今天的画风不太对,劝退预警。T1不是很送分,T2看起来不友善,T3难道是树上动态dp??这是什么神仙操作,动态dp不是去年WC的新知识点吗,而且一上来就考树上动态dp??我考前还一直以为可能会引进数位dp,然后出一道数位dp的水题。
T1细节比较多,没写 O ( n 2 ) O(n^2) O(n2)的,写了个 O ( n log n ) O(n\log n) O(nlogn)。但是好像写挂了几分,不知道CCF会出什么奇妙的数据。
然后就去看T2,以为只要保证每条斜线递减即可,高高兴兴地写状压dp。结果第二个样例都没过,然后以为我状压写挂了调试了一会,发现思路有问题。然后就先去看了T3,然后题目看错了。结果大样例过不去,当时一想,T2和T3都没分。。所以又回去做T2了,最后发现状压可以过n=2的点。
下考前一直没发现看错了T3的题意,直到下考后Dimitry_L告诉我看错题了…晚节不保
在洛谷上测的总分只有100+100+85+72+55+0=412
完全不应该浪费时间在T2上的,T2写完50分就应该赶紧丢,这样的话可能T3还能拿60+。另外感觉今年的题目区分度不够啊,可能分数会密集地分布在 [ 400 , 500 ] [400,500] [400,500]这个区间,wc无望了。。感觉像考了一次弱省省选。
下午思考了一下人生,至少感觉好多了,可能以后我会称D2T2为“一道送我退役的好题”吧。。
后续
猫锟说D2T3不是他出的,而且有一个离线后倍增的NOIP考点做法。
??强行NOIP考点?这实质上和动态DP的思想一致啊
现在想想觉得自己的心态还是大有问题,被难度设置打了个措手不及之后就慌了神,策略完全失误了。紧张感导致我没有按照最优策略去再搞搞D2T3,不然打好68分的暴力,可以说是比较正常的发挥吧,也能给HN的各位神仙垫个底了。。
而且做T2也没有往打表找规律的方向去思考,最后1.5h其实就没有拿分。求稳为重…
部分题解
D1T3
好像很多神仙都做过原题,应该算是一道看起来比较套路的题目。考场的时候脑子一抽想着方便实现就从后往前删死活过不了大样例。
显然可以二分,那么对于一个值mid,统计不短于mid的路径可以选出多少条。我们可以证明选取的道路的lca深度越深越优秀,那么就可以贪心了,在每一个点拿set存下已有的链的长度,然后考虑从小到大依次配对。
#include <cstdio>
#include <set>
using namespace std;
typedef long long ll;
const int maxn=50010;
template <typename Tp> int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> void read(Tp &x)
{
x=0;char ch=getchar();int f=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
struct data{int v,w,nxt;}edge[maxn<<1];
int n,m,p,l,r,mid,cnt,ans,head[maxn];
multiset<int> s[maxn];
multiset<int>::iterator itr;
void insert(int u,int v,int w)
{
edge[++p]=(data){v,w,head[u]};head[u]=p;
edge[++p]=(data){u,w,head[v]};head[v]=p;
}
void input()
{
int u,v,w;
read(n);read(m);
for(int i=1;i<n;i++)
{
read(u);read(v);read(w);
insert(u,v,w);r+=w;
}
}
int dfs(int x,int pre)
{
int res=0,tmp;
s[x].clear();
for(int i=head[x];i;i=edge[i].nxt)
if(edge[i].v^pre)
{
tmp=dfs(edge[i].v,x);
if(tmp+edge[i].w>=mid) ++cnt;
else s[x].insert(tmp+edge[i].w);
}
while(s[x].size()>0)
{
tmp=*s[x].begin();
s[x].erase(s[x].begin());
itr=s[x].lower_bound(mid-tmp);
if(itr!=s[x].end()) ++cnt,s[x].erase(itr);
else getmax(res,tmp);
}
return res;
}
int main()
{
freopen("track.in","r",stdin);
freopen("track.out","w",stdout);
input();
while(l<=r)
{
mid=(l+r)>>1;cnt=0;
dfs(1,1);
if(cnt>=m) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}
D2T2
神仙题,推导难度比D2T3难多了。。
满足条件的充要条件是
- ∀ i ∈ ( 0 , n ) , j ∈ ( 0 , m ) A i , j ≥ A i − 1 , j + 1 \forall_{i\in(0,n),j\in(0,m)} A_{i,j}\geq A_{i-1,j+1} ∀i∈(0,n),j∈(0,m)Ai,j≥Ai−1,j+1
- A x , y = A x − 1 , y + 1 ⇒ ∀ i ∈ ( x , n ) , j ∈ ( y , m ) A i , j = A i − 1 , j + 1 A_{x,y}=A_{x-1,y+1}\Rightarrow\forall_{i\in(x,n),j\in(y,m)}A_{i,j}=A_{i-1,j+1} Ax,y=Ax−1,y+1⇒∀i∈(x,n),j∈(y,m)Ai,j=Ai−1,j+1
再者就是大力分情况讨论,对每条对角线计数。由于详细讲解会花费大量的篇幅,所以就丢一篇良心讲解
#include <algorithm>
#include <cstdio>
#define rg register
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
int n,m,a1,a2,a3,ans,f[10];
inline int pls(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int pp(int x){return pls(x,x);}
int power(int x,int y)
{
int res=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1)
res=(ll)res*x%mod;
return res;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
read(n);read(m);
if(n>m) swap(n,m);
if(n==1){printf("%d\n",power(2,m));return 0;}
if(n==2){printf("%lld\n",4ll*power(3,m-1)%mod);return 0;}
if(n==3){printf("%lld\n",112ll*power(3,m-3)%mod);return 0;}
for(rg int i=2;i<=n;i++) f[i]=pls(pp(pp(f[i-1])),20);
a1=(ll)power(4,n-2)*power(2,n+1)%mod;
a2=5ll*power(4,n-4)*power(2,n+1)%mod;
a3=(ll)(15+pp(f[n-3]))*power(2,n)%mod;
if(n==m){printf("%d\n",pls(a1,pls(a2,a3)));return 0;}
ans=pls(a1,a2)*3ll%mod;
ans=pls(ans,(3ll*f[n-3]+20)%mod*power(2,n));
ans=pls(ans,pls((3ll*f[n-3]+16)%mod*power(2,n)%mod,12ll*power(2,n-1)%mod));
ans=(ll)ans*power(3,m-n-1)%mod;
printf("%d\n",ans);
return 0;
}