??大部分人都覺得t3是道不可做題去剛t1t2了,於是我就僥倖苟到了前面?
這場考試比較成功的就是快速水掉了t1t2的部分分,1h拿到88分起碼為之後硬肝t3上了保險(賽後發現就算t3爆零也能rank15?)
剩下也就沒什麼了……t3的分完全是時間堆出來的,還有運氣成分。因為當時第乙個a掉了二分答案專題的奶牛健美操那道題,所以看到直徑下意識想維護子樹最長鏈+次長鏈,而且要不是前面兩道題都不會我才不敢寫那個噁心至極的分類討論換根qaq。單就方法而言,我打的東西其實挺無腦的,並沒有思考太多針對本題的性質(要不然我還能只拿前兩問的分?),最後莫名其妙不會第三問了。剩下的時間也沒有打中途想到的二維莫隊,覺得時間複雜度沒***得不償失。最後幾十分鐘沒怎麼拿分。
不過拿到t3的分至少證明自己**能力和除錯能力有了提公升?(yy什麼呢還是一如既往的菜)
看到自己前面的4位大佬都a題了,差一點碾碎我的lockeya掉了t2,自己不過是三道題都騙了點分而已。前路還漫長啊。
神dp。除了單調棧還有二次函式優化??
先丟個比較詳細的題解
至於為什麼盡量把坑填到和某一棟樓一樣平是最優的,我也不會證
把當前位置$i$作為坑的右邊緣,列舉坑的左邊緣$j$,找能填的位置$k$,可得轉移:
$f[i]=\sum \limits _^(t-h_k)^+c*(h_j+h_i-2*t)+f[j]$
想怎麼優化轉移。首先要避免列舉所有位置。可以維護乙個單調遞減的單調棧,這樣就確保棧裡的元素一定可以轉移給當前的$i$。
然後進行尋找最優解的優化。觀察到這個轉移方程是乙個二次函式,化簡一下就可以得到它的一次項、二次項、常數項係數。
那自變數$t$當然是取對稱軸處($- \frac$)最優啦,但是要注意取對稱軸的答案是否合法。特判之。
計算對稱軸四捨五入。
#include#include#include#includeusing namespace std;typedef long long ll;
const int n=1e6+5;
int n;
ll c,h[n],sum[n],sum[n],f[n];
int s[n],top;
ll cacl(int l,int r,ll val)
int main()
h[0]=h[n+1]=0x7fffffff;
for(int i=1;i<=n+1;i++)
cout《二維莫隊水之。注意指標移動的先後順序。
#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
int read()
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}const int n=205,m=3e5+5;
int n,m,q;
int a[n][n],type,bl,ans[m],res,bu[n*n];
maplink;
struct query
while(xqxx)
while(y>qy)
while(yqyy)
//cout《我寫的是噁心至極的換根……思維直接粗暴,細節稍多。
首先一遍dfs找出$x$的子樹中的點到$x$的最長距離$dis[x]$,以及$x$子樹中的直徑$len[x]$,後者直接維護最長鏈和次長鏈就能得到。
然後考慮:如果我們斷掉一條邊,把樹變成兩個聯通塊,那麼他們重新相連後的最短直徑是?
很顯然,聯通塊1的直徑、聯通塊2的直徑、兩條直徑的二分之一向上取整再相加後+1,這三者取$max$。最後那個的含義就是把兩條直徑的終點連在一起。
題解的做法是每個點維護子樹字首聯通塊和字尾聯通塊的直徑端點即可快速合併,但我不太會維護端點,所以直接利用大量的鏈長資訊進行換根dp,每次分類討論得到結果。這樣相當與列舉了每條邊斷掉後的結果,所以一定能遍歷所有情況、找到所有可能斷的邊。
這個換根的過程要考慮很多東西:父親到兒子的過程中子樹直徑已經求出,但外部聯通塊的直徑需要額外維護。這個外部直徑可能還是原來的外部直徑,也有可能是經過剛剛被扔到外面的父親的直徑。
所以在轉移的時候可能要維護最大值、次大值、再次大值。為什麼?我們向兒子轉移的時候需要除這個兒子的資訊之外另外的兩個極值來進行比較和拼湊出直徑。如果這個兒子就是最大值的提供者,那肯定就不能用最大值來算外部直徑了。總之很麻煩,看**吧。(逃
這樣就可以求出前兩問的結果。至於第三問,先從第二問結果裡隨便挑一條邊刪了,然後取產生的這兩個聯通塊的直徑中點即可。
#include#include#include#include#include#define pa pairusing namespace std;
int read()
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}const int n=3e5+5;
int n;
int to[n<<1],head[n],nxt[n<<1],tot=1,id[n<<1],dis[n],len[n];
int s[n<<1],top,ans=0x3f3f3f3f,del;
pa e[n<<1];
void add(int x,int y,int i)
void dfs1(int x,int f)
int m1,m2,m3,nowl,nl1,nl2;
for(int i=head[x];i;i=nxt[i]) }
int s,maxd,pre[n],t;
vectorlink;
void dfs3(int x,int f,int dep)
}void dfs4(int x,int f,int dep)
}void getdis(int x)
int main()
dfs1(1,0);dfs2(1,0,0,0,0);
cout
cout
cout
del=s[top];
int node1=e[del].first,node2=e[del].second,node3,node4;
getdis(node1);
int sz=link.size();
node3=link[sz/2];
getdis(node2);
sz=link.size();
node4=link[sz/2];
cout
}
CSP S模擬測試94 題解
高精硬上似乎跑不過,其實可以都取個 log 那麼只需要比較 y times log x 和 sum limits y log i 就好了。includeusing namespace std int t double x,y void work int main 顯然目標區間合法的充要條件是 把位置...
CSP S模擬測試69 題解
一如既往的垃圾,又回到了那個場場墊底的自己,明明考場上都想到正解了,但是就是拿不到分,可能是互奶把rp用光了吧以後一定加強訓練 能力。t1 考場上一直yy矩陣快速冪,雖然自己矩陣快速冪一點都不會還是硬著頭皮yy,發現不可做之後並沒有及時轉化思路,但其實自己預處理的陣列就是正解。切記 不僅矩陣快速冪是...
CSP S 模擬測試 51 題解
慣例先看一遍三道題,t1 一開始反應要求割點,但是這是有向圖,肯定不能求割點,康了一下資料範圍,有40 是樹的,還不錯,決定待會在打。看t2 字串題,完了我字串最弱了,肯定只能打暴力了,帶著前兩題都不會的心情,看了t3發現是期望,完了爆0了,在一看,發現是sb原題,還簡單一點,趕緊把t3碼了一遍過大...