Noip模擬33墊底反思 2021.8.8
T1 Hunter
考場上沒寫$%p$掛了25分。也是很牛皮,以後打完過了樣例一定要檢查
因為樣例太小了。。。。。。很容易忘記%%%%
正解隨便手模就出來了。
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int NN=1e5+5,p=998244353; 5 int n,w[NN],ans; 6 inline int qmo(int a){ 7 int ans=1,b=p-2,c=p; a%=c; 8 while(b){ if(b&1View Code) ans=(ans*a)%c; b>>=1; a=(a*a)%c; }return ans; 9 } 10 namespace WSN{ 11 inline short main(){ 12 scanf("%lld",&n); for(int i=1;i<=n;i++) scanf("%lld",&w[i]); 13 for(int i=2;i<=n;i++) (ans+=w[i]*qmo((w[1]+w[i])%p)%p)%=p; 14 printf("%lld\n",ans+1); return0; 15 } 16 } 17 signed main(){return WSN::main();}
T2 Defence
據說是很水的動態開點權值線段樹板子。。。。。
想到用線段數維護的值,但是不會打動態開點了。。。
資料結構太弱了,碼力太弱了。。。。。決定以後有時間就打資料結構
噁心死自己的那種。。。盯著程式碼望穿秋水的那種。。。
基本思路:
維護的資訊有第一個一的位置,最後一個一的位置,區間內最長的$0$串的長度
每個點開一顆權值線段樹,維護當時使用完法術後的序列資訊
然後$dfs$到葉子節點向上做線段樹合併,在合併的時候統計節點的資訊記錄答案就行了。
真是做過的題也不記得了,這不就是
原來資料結構學習的太不走心了,以後是要背鍋的,前面付出的太少了。。。。
程式碼能力是要一點一點練的,不是想想題看看程式碼就會的,以後一定要多自己碼,唉~
思路是很簡單的,考場上還是可以想到的,但是被自己的碼力限制了,苦惱
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int NN=1e5+5; 4 int n,m,q,rt[NN],ans[NN]; 5 struct SNOW{int to,next;};SNOW e[NN<<1];int head[NN],rp; 6 inline void add(int x,int y){e[++rp]=(SNOW){y,head[x]}; head[x]=rp;} 7 struct SNOWtree{ 8 int seg,ls[NN*40],rs[NN*40]; 9 int pre[NN*40],nxt[NN*40],len[NN*40]; 10 inline void pushup(int x){ 11 if(!ls[x]){pre[x]=pre[rs[x]]; nxt[x]=nxt[rs[x]]; len[x]=len[rs[x]]; return;} 12 if(!rs[x]){pre[x]=pre[ls[x]]; nxt[x]=nxt[ls[x]]; len[x]=len[ls[x]]; return;} 13 int lenth=pre[rs[x]]-nxt[ls[x]]-1; 14 len[x]=max(lenth,max(len[ls[x]],len[rs[x]])); 15 pre[x]=min(pre[ls[x]],pre[rs[x]]); 16 nxt[x]=max(nxt[ls[x]],nxt[rs[x]]); 17 } 18 inline void insert(int &x,int l,int r,int pos){ 19 if(!x) x=++seg; 20 if(l==r){ 21 pre[x]=nxt[x]=pos; 22 len[x]=0; 23 return; 24 }int mid=l+r>>1; 25 if(pos<=mid) insert(ls[x],l,mid,pos); 26 else insert(rs[x],mid+1,r,pos); 27 pushup(x); 28 } 29 inline void merge(int &x,int y,int l,int r){ 30 if(!x||!y) {x=x+y;return;} 31 if(l==r){ 32 if(pre[y]){ 33 pre[x]=nxt[x]=l; 34 len[x]=0; 35 } 36 return; 37 }int mid=l+r>>1; 38 merge(ls[x],ls[y],l,mid); 39 merge(rs[x],rs[y],mid+1,r); 40 pushup(x); 41 } 42 }tr; 43 inline void dfs(int f,int x){ 44 for(int i=head[x];i;i=e[i].next){ 45 int y=e[i].to; if(y==f) continue; 46 dfs(x,y); 47 tr.merge(rt[x],rt[y],1,m); 48 } 49 if(!tr.pre[rt[x]]) ans[x]=-1; 50 else ans[x]=max(tr.pre[rt[x]]+m-tr.nxt[rt[x]]-1,tr.len[rt[x]]); 51 } 52 namespace WSN{ 53 inline short main(){ 54 scanf("%d%d%d",&n,&m,&q); 55 for(int i=1,u,v;i<n;i++){ 56 scanf("%d%d",&u,&v); 57 add(u,v); add(v,u); 58 } 59 for(int i=1,u,pos;i<=q;i++){ 60 scanf("%d%d",&u,&pos); 61 tr.insert(rt[u],1,m,pos); 62 }dfs(0,1); 63 for(int i=1;i<=n;i++) printf("%d\n",ans[i]); 64 return 0; 65 } 66 } 67 signed main(){return WSN::main();}View Code
T3 Connect
本次考試第二坑點,打了$spj$函式卻沒有呼叫。。。。失掉20分。。
兩處失誤當時只要是挽回一處都不會墊底。。。。
以後考試結束前十分鐘一定要抽出時間檢查自己提交的程式碼,不能再出失誤了。。
資料範圍提示狀態壓縮$dp$,思路比較神
$1$號點到$N$的路徑唯一相當於存在一條$1$到$N$的鏈, 並且不在鏈上的每個聯通塊最多隻和鏈上的一個點有連邊
類似這樣。那麼我們要預處理出來的值就知道了。
$sum[S]$表示狀態$S$的聯通塊中的邊權總和
$to[S][i]$表示聯通塊$S$到$i$點的連邊總和
那麼$dp_{S,i}$就表示目前的狀態為$S$,鏈的末端點為$i$的邊權最大值,最後用總邊權減去就可以得到刪去邊的最小值
看題解是完全能看明白的,粘一張圖片
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int NN=17; 5 int n,m,g[NN][NN],U,dp[1<<NN][NN],sum[1<<NN],to[1<<NN][NN]; 6 inline void pre(){ 7 for(int S=1;S<=U;S++) for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) 8 if((S>>i&1)&&(S>>j&1)) sum[S]+=g[i][j]; 9 for(int S=1;S<=U;S++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) 10 if((S>>j&1)&&g[i][j]) to[S][i]+=g[i][j]; 11 } 12 namespace WSN{ 13 inline short main(){ 14 scanf("%lld%lld",&n,&m); U=(1<<n)-1; 15 for(int i=1,u,v,w;i<=m;i++){ 16 scanf("%lld%lld%lld",&u,&v,&w);--u;--v; 17 g[u][v]=g[v][u]=w; 18 } 19 pre(); memset(dp,-1,sizeof(dp)); 20 dp[1][0]=0; 21 for(int S=1;S<=U;S++) for(int i=0;i<n;i++){ 22 if(dp[S][i]==-1)continue; 23 for(int j=0;j<n;j++) if(!(S>>j&1)&&g[i][j]) dp[S|(1<<j)][j]=max(dp[S][i]+g[i][j],dp[S|(1<<j)][j]); 24 int CS=U^S; 25 for(int j=CS;j;j=(j-1)&CS) dp[S|j][i]=max(dp[S|j][i],dp[S][i]+to[j][i]+sum[j]); 26 }printf("%lld\n",sum[U]-dp[U][n-1]); 27 return 0; 28 } 29 } 30 signed main(){return WSN::main();}View Code
連續兩次了,這次比上一次考得還糟糕,上次明顯是T1比較傻,沒想到用優先佇列優化,這次更噁心
直接掛分掛到墊底要知道離真正的考試越來越近了,要是現在模擬的時候再不認真,最後你一定會後悔現在你的所做所為,
就像你今天改T2時候瘋狂不知道如何打出動態開點一樣傻 ,反正機會越來越少,怎麼也沒辦法逃脫進B的事實,
原來不管是真的沒有思路也好,一場因為沒有關freopen也好,還是因為馬虎錯誤掛分也好,都已經為分層的失敗作出了大貢獻,
而且還是不能改變的貢獻。消除這些負貢獻的最好方法不是考完試之後找回很快把題改完,這頂多表示你對這些題都有一定的思路,其他還有什麼呢
你有思路為什麼不能考場上A掉呢?為什麼不能用程式碼實現思路呢?還是之前語言學習時候的不走心,或是當時對OI的偏見。
不過,你現在的成績就是不理想,反映出來的就是你實力不行,就是你還無法達到標準。再怎麼解釋也沒用,
從小就比較反感那些考完試拍大腿的人,結果也快活成那樣了,要改變呀~~~。