前言
點選檢視程式碼
《看得最遠的地方》
你是第一個發現我
越面無表情越是心裡難過
所以當我不肯落淚地顫抖
你會心疼的抱我在胸口
你比誰都還了解我
內心的渴望比表面來得多
所以當我跌斷翅膀的時候
你不扶我但陪我學忍痛
我要去看得最遠的地方
和你手舞足蹈聊夢想
像從來沒有失過望受過傷
還相信敢飛就有天空那樣
我要在看得最遠的地方
披第一道曙光在肩膀
被潑過太冷的雨滴和雪花
更堅持微笑要暖得像太陽
你比誰都還了解我
內心的渴望比表面來得多
所以當我跌斷翅膀的時候
你不扶我但陪我學忍痛
我要去看得最遠的地方
和你手舞足蹈聊夢想
像從來沒有失過望受過傷
還相信敢飛就有天空那樣
我要在看得最遠的地方
披第一道曙光在肩膀
被潑過太冷的雨滴和雪花
更堅持微笑要暖得像太陽
有時候覺得我們很不一樣
你能看見我看不到的地方
有時候又覺得我們很像
都愛仰起頭不聽命運的話
我要去看得最遠的地方
和你手舞足蹈聊夢想
像從來沒有失過望受過傷
還相信敢飛就有天空那樣
我要在看得最遠的地方
披第一道曙光在肩膀
被潑過太冷的雨滴和雪花
更堅持微笑要暖得像太陽
今天是拉開座位完全斷網並強制使用 windows 打的,用局長 long long time ago 放在 ftp 上的虛擬機器,我去不知道為啥那麼“好用”,蚌埠煮了。
然後下虛擬機器耽誤了好長時間……
T1 又放貪心,丫的小樣例沒過我怎麼敢測大樣例的?大樣例過了?我去那我做法是不是假的為啥小樣例過不去……
之後做 T2,因為 T1 沒過動不動回去看……
賽後看題解發現 T1 是對的,但我忘記算他連父親那條邊了……
昨天推了首毛不易的歌,所以【資料刪除】了,後來發現太唐了不可能寫完,就咕著吧,剛才又看了別人的【資料刪除】,有點震撼,原諒我過於冷血只感到了震撼,好像這種無法與我的經歷引起共鳴的東西,我看了只會感到自卑與同情,原諒我這卑微的一生。
明天還有模擬賽,打了沒啥問題,但我後天不想打,想打打板子,不知道能不能商量一下,huge 不是說可以在三場裡選一場不打嗎?
T1 隨機遊走
是道貪心,考慮臨項交換(好吧我之前不知道這玩意叫這名字),發現 \(x\) 在 \(y\) 前有 \(\dfrac{t_x}{w_x}<\dfrac{t_y}{w_y}\),按這個排序即可。
點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N=5e5+10;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char a=getchar_unlocked();
for(;!isdigit(a);a=getchar_unlocked()) if(a=='-') z=0;
for(;isdigit(a);a=getchar_unlocked()) x=(x<<1)+(x<<3)+(a^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,c[N],w[N],dis[N],sum[N]; ll ans,tim; vector<int>e[N];
inline void dfs1(int x)
{
dis[x]=c[x],sum[x]=w[x];
for(int y:e[x]) dfs1(y),dis[x]+=dis[y],sum[x]+=sum[y];
}
inline void dfs2(int x) {ans+=tim*w[x]; for(int y:e[x]) tim+=c[y],dfs2(y);}
signed main()
{
freopen("walk.in","r",stdin),freopen("walk.out","w",stdout);
read(n);
for(int i=2,fa;i<=n;i++) read(fa,c[i]),e[fa].push_back(i);
for(int i=1;i<=n;i++) read(w[i]); dfs1(1);
for(int i=1;i<=n;i++) sort(e[i].begin(),e[i].end(),[&](int x,int y){return 1ll*dis[x]*sum[y]<1ll*dis[y]*sum[x];});
dfs2(1),write(ans);
}
T2 分發獎勵
類似線段樹分治到一個節點就把貢獻加進去,出來就撤銷,但這題本來就在樹上所以直接跑就好,用線段樹維護最小值個數。
點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
#define mid (l+r>>1)
#define ls (mid<<1)
#define rs (mid<<1|1)
using namespace std;
const int N=5e5+10;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char a=getchar_unlocked();
for(;!isdigit(a);a=getchar_unlocked()) if(a=='-') z=0;
for(;isdigit(a);a=getchar_unlocked()) x=(x<<1)+(x<<3)+(a^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,m,tot,in[N],out[N],dep[N],ans[N],sum[N<<1],val[N<<1],add[N<<1];
vector<int>e[N]; set<int>s[N];
inline void dfs(int x)
{in[x]=++tot; for(int y:e[x]) dep[y]=dep[x]+1,dfs(y); out[x]=tot;}
inline void pushup(int p,int l,int r)
{
if(val[ls]<val[rs]) val[p]=val[ls],sum[p]=sum[ls];
else if(val[ls]>val[rs]) val[p]=val[rs],sum[p]=sum[rs];
else val[p]=val[ls],sum[p]=sum[ls]+sum[rs];
}
inline void build(int p,int l,int r)
{
if(l==r) return sum[p]=1,void();
build(ls,l,mid),build(rs,mid+1,r),pushup(p,l,r);
}
inline void spread(int p,int l,int r)
{val[ls]+=add[p],add[ls]+=add[p],val[rs]+=add[p],add[rs]+=add[p],add[p]=0;}
inline void change(int p,int l,int r,int vl,int vr,int d)
{
if(vl<=l&&vr>=r) return val[p]+=d,add[p]+=d,void();
if(add[p]) spread(p,l,r); if(vl<=mid) change(ls,l,mid,vl,vr,d);
if(vr>mid) change(rs,mid+1,r,vl,vr,d); pushup(p,l,r);
}
inline void solve(int x)
{
for(int y:s[x]) change(1,1,n,in[y],out[y],1);
ans[x]=val[1]?n-1:max(0,n-1-sum[1]); for(int y:e[x]) solve(y);
for(int y:s[x]) change(1,1,n,in[y],out[y],-1);
}
signed main()
{
freopen("reward.in","r",stdin),freopen("reward.out","w",stdout);
read(n,m); for(int i=2,x;i<=n;i++) read(x),e[x].push_back(i);
dfs(1),build(1,1,n); for(int i=1,x,y;i<=m;i++)
{
read(x,y); if(dep[x]>dep[y]) swap(x,y);
if(in[x]<=in[y]&&out[x]>=in[y]) s[x].insert(x);
else s[x].insert(x),s[y].insert(y),s[x].insert(y),s[y].insert(x);
}
solve(1); for(int i=1;i<=n;i++) write(ans[i]),putchar_unlocked(' ');
}
T3 卡路里
好像比前兩題簡單,賽時還沒看,直接單調棧加二維查分就可以了。
點選檢視程式碼
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define sort stable_sort
using namespace std;
const int N=210,M=5010;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=true;
register char a=getchar_unlocked();
for(;!isdigit(a);a=getchar_unlocked()) if(a=='-') z=0;
for(;isdigit(a);a=getchar_unlocked()) x=(x<<1)+(x<<3)+(a^48);
x=(z?x:~x+1);
}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y){read(x);read(y...);}
template<typename Tp> inline void wt(Tp x){if(x>9)wt(x/10);putchar_unlocked((x%10)+'0');}
template<typename Tp> inline void write(Tp x){if(x<0)putchar_unlocked('-'),x=~x+1;wt(x);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x);putchar_unlocked(' ');write(y...);}
int n,m,l[M],r[M],sta[M],a[N][M]; ll ans=-1e9,d[M],sum[M][M];
signed main()
{
freopen("calorie.in","r",stdin),freopen("calorie.out","w",stdout);
read(n,m); for(int i=2;i<=m;i++) read(d[i]),d[i]+=d[i-1];
for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) read(a[j][i]);
for(int i=1;i<=n;i++)
{
sta[0]=0; for(int j=1,top=0;j<=m;j++)
{
while(top&&a[i][sta[top]]<=a[i][j]) top--;
l[j]=sta[top]+1,sta[++top]=j;
}
sta[0]=m+1; for(int j=m,top=0;j;j--)
{
while(top&&a[i][sta[top]]<a[i][j]) top--;
r[j]=sta[top]-1,sta[++top]=j;
}
for(int j=1;j<=m;j++)
{
sum[l[j]][j]+=a[i][j],sum[j+1][r[j]+1]+=a[i][j];
sum[j+1][j]-=a[i][j],sum[l[j]][r[j]+1]-=a[i][j];
}
}
for(int i=1;i<=m;i++) for(int j=1;j<=m;j++)
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
for(int i=1;i<=m;i++) for(int j=i;j<=m;j++)
ans=max(ans,sum[i][j]-d[j]+d[i]); write(ans);
}
T4 傳話遊戲
咕咕咕。