牛客CSP S提高組賽前集訓營5 解題報告

2022-05-19 21:41:03 字數 3201 閱讀 8526

linker

總分 : 100 + 100 + 40 = 240

結論題。無論如何神j都會贏。

最優決策:神樹變化了我就不變,神樹不變我就變化。

#includeusing namespace std;

typedef long long ll;

const int mod=998244353;

inline ll pow(ll pre, int x)

int n;

int main()

狀壓dp水題。

暴力都沒有去切,因為k太小了,直接狀壓走過那些邊即可。

//**有點醜,但是考試的時候挺快就敲出來了。

#include#define re register

#define rep(i,a,b) for(re int i=a,i##end=b; i<=i##end; i++)

#define drep(i,a,b) for(re int i=a,i##end=b; i>=i##end; i--)

#define repp(i,a,b) for(re int i=a,i##end=b; ii##end; i--)

#define erep(i,x) for(re int i=head[x]; i; i=edge[i].nxt)

#define lowbit(x) ((x)&-(x))

#define debug(x) cerr<<#x<<" = "<#define pll pair#define fi first

#define se second

#define coint const int

#define coll const ll

#define cm cerr<<(&s2-&s1)/1024./1024<<"mb"templateinline t max(const t &x, const t &y)

templateinline t min(const t &x, const t &y)

struct edge2;

vectorg[n];

vectorvec;

int n,m,k;

int mark[n],id[n];

ll dis[k<<1][n];

ll dp[(1<_.val; }

};struct heap

} }// rep(i,1,n) printf("%d -> %d : %lld\n",st,i,dis[id][i]);

return;

}bool s2;

int main()

} mark[1]=1;

rep(i,1,n) if(mark[i]) vec.push_back((int)i),id[i]=((int)vec.size())-1;

ms(mark,-1); ms(dis,0x3f);

repp(i,0,vec.size()) dijkstra(i,vec[i]);

ms(dp,0x3f);

coll inf=dp[0][0];

dp[0][0]=0;

repp(sta,0,(1<=inf) continue;

int at=vec[i];

repp(j,0,(int)g[at].size())

} }ll ans=inf;

repp(i,0,vec.size())

ans=min(ans,dp[(1<(pre_dfs與dfs_top是樹鏈剖分的部分。)

p30直接暴力\(o(n^3)\)處理處每兩個點間最小dis值

struct p30

rep(i,1,n)

x=f[x];

}} rep(i,1,m)

printf("%lld\n",dis[s][t]);

} return;

}}p30;

p40

可以發現詢問數量很小,我們直接對於每個詢問暴力向上跳,而我們總共就會處理\(n^2\)個點之間的距離,中間重複處理的還可以省去,因此總複雜度不到\(o(n^2)\)

struct p40

rep(i,1,m)

int x=t,fa=f[s];

if(!mark[s][t]) while(x!=fa)

int y=t;

while(y!=x)

mark[x][t]=1;

x=f[x];

}printf("%lld\n",dis[s][t]);

} return;

}}p40;

p70

可以發現在向下跳的過程中,我們經過的點是單調遞減的,因此利用倍增思想,記錄下乙個走到的點,以及其花費,然後倍增處理處即可。

struct p_chain

if(tp[0][x]) dis[0][x]=x*(dis[tp[0][x]]-dis[x]);

} return;

} inline void solve()

} rep(i,1,m)

ll ans=0;

drep(j,19,0)

stk[++tail]=x;

}} return; }

struct elementb[n];

inline int get_element(int x, int y)

b[++cnt]=(element)<%x,y%>;

return cnt; }

inline void solve()

} while(m--)

if(l[t]r[s])

int cnt=get_element(s,t);

ll ans=0;

int mn=s;

drep(i,cnt,1)

if(to[0][l] && l[to[0][l]]<=l[r]) ans+=mn*(dis[to[0][l]]-dis[l]),l=to[0][l],mn=l;

drep(j,19,0)

if(i>1) ans+=mn*(dis[b[i-1].l]-dis[l]);

else ans+=mn*(dis[r]-dis[l]);

}printf("%lld\n",ans);

} return;

} }p100;

鏈的30分沒拿到真的不應該。思維還得更加活躍才可以。

牛客CSP S提高組賽前集訓營2

然後隨便用乙個資料結構維護一下就行了,我寫的線段樹。我們先找出每個環,然後我們先刪連線環的邊,每刪一條就可以多產生乙個聯通塊,在考慮刪環邊,發現從最大的環刪起一定最優 因為你刪的第一條邊得不到任何新的聯通塊 就很容易想到tar jantarjan tarjan 發現你只能寫出80 8080 分,因為...

牛客CSP S提高組賽前集訓營1

比賽鏈結 官方題解 before t1觀察 結論題,t2樹形dp,可以換根或up down,t3正解妙,轉化為圖上問題。題目質量不錯,但資料太水了 一共n個石子堆,每個石子堆有ai個石子,兩人輪流對石子塗色 先手塗紅,後手塗藍 且需要保證當前回合塗的石子顏色不能和它相鄰的兩個同色,誰塗不下去誰輸。一...

牛客CSP S提高組賽前集訓營5(待更)

題目描述 神樹大人造了乙個長為n的01序列,並邀請無所事事的神j來和他博弈。每一輪裡,若這個序列的第1項是0,那麼神樹大人可以選擇讓它不變或者變成1 若這個序列的第1項是1,那麼神j可以選擇讓它不變或者變成0。接著對這個序列進行旋轉操作 即將第1項放到第n項的後面,其他項依次替補。如果這個序列變為全...