省選模擬12

2022-09-20 13:18:13 字數 1664 閱讀 1510

\(f_i\) 表示以 \(i\) 為結尾的答案,然後轉移為 \(f_i=\max\limits_^(f_j+(a_i-a_j)^2+c)\)

這樣會有不合法的情況無法轉移,就是兩個數之間有比他倆都大的值

但是這樣的值一定會比從最大值轉移要劣,所以直接斜率做一下就行

code

#include#define int long long

#define lson rt<<1

#define rson rt<<1|1

#define rint signed

#define inf 0x3f3f3f3f3f3f3f3f

using namespace std;

inline int read()

while(ch>='0'&&ch<='9')

return x*f;

}int n,c,ans;

int a[1000010],f[1000010];

inline int sq(int x)

struct node

}st[1000010*4];

inline bool cover(node a,node b,int x)

void build(int rt,int l,int r)

void ins(int rt,int l,int r,node k)

int query(int rt,int l,int r,int pos)

signed main());

for(int i=2;i<=n;i++));

} printf("%lld\n",f[n]);

return 0;

}

先詢問出全域性的最大差值,然後二分乙個位置找到任意乙個極值的位置

因為每個數都不一樣,於是與極值作差的結果也都不一樣

再按二進位制位拆分,每個差值都會在是二進位制下是 \(1\) 的那一位出現一次

於是就能找出每個位置與極值的差,然後再找出最大的那個位置

詢問一下,看看一開始的值是最大值還是最小值然後就能知道出所有數的值了

code#include "difference.h"

#includeusing namespace std;

namespace ttt

for(int i=0;(1<>i&1;

vec.clear();

for(int j=1;j<=n;j++) if((j>>i)&1) if(j-1!=pos) vec.emplace_back(j-1);

s=qry2(vec);for(auto l:s) mp[i][l]--;

vec.clear();

for(int j=1;j<=n;j++) if((j>>i)&1) if(j-1!=pos) vec.emplace_back(j-1);

vec.emplace_back(pos);

s=qry2(vec);for(auto l:s) mp[i][l]++;

} for(int i=0,sum;i>j)&1)else for(auto l:mp[j]) if(l.second!=0) t[l.first]+=1000;

for(auto l:t) if(l.second==sum) c[i]=l.first;

} for(int i=0,tmx=-1;i

咕咕咕

省選模擬12 題解

暴力做法是直接bfs。優化的方法是離散化。將特殊的點的橫縱座標抽出來,然後用這些橫縱座標為1e12 1e12分成乙個個塊,容易發現每個塊內的狀態是一致的。然後用與暴力類似的方法即可,注意最後統計的是每個塊的實際大小。觀察可知資料範圍欺騙了你。似乎剪枝 注意去重複狀態 的搜尋就能過。乙個更合理的做法是...

省選模擬 19 09 11

ps.博主趁資訊課摸魚考的暴零模擬 看門人憑感覺就知道是長鏈剖分,將路徑查分一下,dis u di sv 2 dis lc adis u dis v 2 dis disu disv 2 disl ca 維護fu,if fu,i 表示u的子樹,深度為 i 的點的 dis disdi s最大值 考慮如何...

省選模擬96

容易發現當 k 3 時無解。然後容易證明當 k 3 時,只有 m 3 才是有解的。然後直接做不好做,考慮欽定然後容斥出合法方案。對於 k 3 列舉乙個點,然後計算另乙個的方案數。其他情況類似,欽定滿足條件的角,然後容斥。然後對於每乙個 o n 的式子用組合恒等式大力化簡就可以做到 o 1 了。考慮每...