並不知道該怎麼寫... 算了仍是按照標準劇情來吧c++
這應該是一篇寫得很是差的流水帳...優化
省選前在機房的最後一天。ui
壓力並非很大,畢竟聯賽 JL rank 1。spa
晚上動員,和同窗制定了策略:不管如何都不要掛題(flag)。c++11
清明。code
前一天晚上(其實應該是這一天早上)夢見了本身一試考掛... 後來就醒了... 頹了一上午。博客
下午母上回來,不頹不頹,開始更博客。string
後來因爲各類緣由,最終只更了兩篇... 感受效率好低...it
九省聯考一試。io
早上來得不算晚,和同窗一塊兒奶題,奶了一些都沒出的東西...
開始抽籤,抽到了10號,左邊9號l1ll5,左前方8號JZYshuraK。
進了考場,到了8點,解壓,稀裏糊塗地開始看題。
Woc T1 什麼鬼?看數據範圍猜了個 $O(n^6)$ 的貪心。
Woc T2 什麼鬼?貪心?老子確定能猜出來。
Woc T3 什麼鬼?等等我好像會寫 $O(n^3)$ 暴力... 那就夠了。
推了下 T1 的大樣例發現不對,感受必定不是裸貪心,因而想狀壓。把狀態數打出來發現只有 18W 左右所以狀壓dp一下好像能過。寫了個正着的dp發現WA了,想到前後手決策不一樣,反過來推,過了大樣例。
T2 猜了個直接貪心法,對拍了1000組發現WA了,原來是有重複數字的鍋。想到 [HNOI2015]菜餚製做 ,正着推不行考慮反着推,即把小的數儘可能放到後面。又具體考慮了一下重複數字的狀況,寫了線段樹,過了樣例及20W組對拍。
T3 看到時間7s直接寫了個 $O(n^3)$ 的暴力,簡單測了一下 $n=1111$ 的狀況發現開long long只需6s左右,使用unsigned int更是跑進了2s。因而卡卡了常,$n=1666$ 的鏈壓到了4s如下。
此時距離考試結束還有1h+,檢查各類 文件名/文件輸入輸出 直到考試結束。
出考場以爲本身老穩了,儘管 T2 每一個人策略不同可能有點慌,然而我過了20W組對拍,不虛。
去日新樓一塊兒吃飯,回來當作績。
按照JL的尿性,成績應該是按照分數從大到小排的。
爲何我都AK了還找不到本身的名字啊...
後來終於在下面某位置找到了本身,rank 10,100/0/0...
考試以前說着千萬不要掛題,可怎麼仍是掛了啊...
回到本身的機器上一探究竟,測了大點發現不對,然而是diff的鍋;測了小點,毫無懸念A了...
各類檢查文件名之類的仍是沒查出錯誤...
最後,我看到了-std=c++11...
想到了什麼不應想到的事情... 我 T2 和 T3 全用的鄰接表存邊... 全使用了next[]...
本機編譯瞭如下果真過不去...
我傻在那裏。200分的差距,一落千丈。
一樣被卡的還有CQzhangyu... 他 T2 沒有用next[]所以還有20pts。
熱鬧是它們的,我什麼也沒有。
再後來,找了各類老師,各類體校學長,仍是沒能把分數找回來... 填了一張申訴表,到如今(2018.04.12)好像還沒發回來...
完了,全完了,涼了,翻車了。
難道我JL現役最強OIer就要省選退役了嗎...
在家哭了一下午,心態卻是好了一些:「老子今天300大家才210,看我明天隨便翻盤」 。
然而晚上仍是睡不着覺,壓力太大了,畢竟須要達成:超過LJ80pts/超過CKH70pts/超過CQ0pts 三者之二才能二試翻盤。折騰了半天終於睡着了。
吉林省選二試。
到了候考室壓力仍是挺大... 強行裝做樂觀的樣子,和其餘人談笑風生。
並不從新抽籤,所以過了一下子就直接進考場了。
。。。
。。。
。。。
而後就沒有而後了。
永遠不要以爲你能翻盤,由於你根本就不知道「盤」是什麼樣子的。
——GXZlegend
T1 裸矩乘,直接秒掉,沒啥意義的題,全場切。
T2 顯然dfs序前驅後繼,直接秒掉,沒啥意義的題,全場切。
T3 暴力36pts。
這他媽還考個P了?白送236pts?
另外你他媽前一天開C++11,今天不開?
出題人你是吃*的嗎?
盡本身最大努力也沒有想出來 T3 怎麼作... 因而儘量優化了搜索的複雜度,最終 T3 拿了64pts。
出考場,好像沒人掛題。只能期望別人文件名寫錯了吧。
最後看分,T2 全場卡一個點95pts,其它的和我想象的徹底一致。
CQzhangyu 切了 T3 ,然而被卡常了,進隊無望。
後來知道JL換題了,氣憤不已,然而已經沒有什麼用了。
至此,學了5年OI的JL隊長GXZlegend,退役了。
和潘老師打了一下午球,晚上老師請吃飯,而後回機房頹了兩個小時,慶祝退役的本身。
狀態數只有 $C_{n+m}^n<190000$ ,所以預處理狀態以後從後往前dp,設 $f[i]$ 表示當前是 $i$ 狀態,下一個取的人最多可以比對手高多少分。轉移時枚舉取哪個便可。
#include <map> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; map<ll , int> mp; int n , m , a[12][12] , b[12][12] , v[12] , c[200010][12] , s[200010] , tot , f[200010]; ll bas[12] , val[200010]; void dfs(int x) { int i; if(x > m) { tot ++ ; for(i = 1 ; i <= m ; i ++ ) c[tot][i] = v[i] , s[tot] += v[i] , val[tot] = val[tot] + v[i] * bas[i - 1]; c[tot][0] = v[0] , mp[val[tot]] = tot; return; } for(i = 0 ; i <= v[x - 1] ; i ++ ) v[x] = i , dfs(x + 1); } int main() { freopen("chess.in" , "r" , stdin); freopen("chess.out" , "w" , stdout); int i , j; scanf("%d%d" , &n , &m); bas[0] = 1; for(i = 1 ; i <= m ; i ++ ) bas[i] = bas[i - 1] * (n + 1); for(i = 1 ; i <= n ; i ++ ) for(j = 1 ; j <= m ; j ++ ) scanf("%d" , &a[i][j]); for(i = 1 ; i <= n ; i ++ ) for(j = 1 ; j <= m ; j ++ ) scanf("%d" , &b[i][j]); v[0] = n , dfs(1); memset(f , 0xc0 , sizeof(f)) , f[tot] = 0; for(i = tot - 1 ; i ; i -- ) { for(j = 1 ; j <= m ; j ++ ) { if(c[i][j] < c[i][j - 1]) { if(s[i] & 1) f[i] = max(f[i] , b[c[i][j] + 1][j] - f[mp[val[i] + bas[j - 1]]]); else f[i] = max(f[i] , a[c[i][j] + 1][j] - f[mp[val[i] + bas[j - 1]]]); } } } printf("%d\n" , f[1]); return 0; }
從後往前貪心,儘可能把小的數放到後面,但這樣處理重複的數可能會錯誤,所以對於出現 $cnt[i]$ 次的 $i$ ,從 $cnt[i]$ 到 $1$ 枚舉放到後面的哪一個位置。使用線段樹上二分解決。
#include <cmath> #include <cstdio> #include <algorithm> #define N 500010 #define lson l , mid , x << 1 #define rson mid + 1 , r , x << 1 | 1 using namespace std; int a[N] , si[N] , head[N] , to[N] , next[N] , cnt , ans[N] , sum[N << 2]; inline void add(int x , int y) { to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt , si[x] += si[y]; } void update(int p , int a , int l , int r , int x) { sum[x] += a; if(l == r) return; int mid = (l + r) >> 1; if(p <= mid) update(p , a , lson); else update(p , a , rson); } int query(int k , int l , int r , int x) { if(l == r) return l; int mid = (l + r) >> 1; if(sum[x << 1 | 1] < k) return query(k - sum[x << 1 | 1] , lson); else return query(k , rson); } int main() { freopen("iiidx.in" , "r" , stdin); freopen("iiidx.out" , "w" , stdout); int n , i , last = 1 , j , l , t; double k; scanf("%d%lf" , &n , &k); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , si[i] = 1; sort(a + 1 , a + n + 1); for(i = n ; i ; i -- ) add((int)floor(i / k) , i); for(i = head[0] ; i ; i = next[i]) update(to[i] , si[to[i]] , 1 , n , 1); for(i = 1 ; i <= n ; i = last) { while(last <= n && a[last] == a[i]) last ++ ; for(j = last - i ; j ; j -- ) { t = query(j , 1 , n , 1) , ans[t] = a[i] , update(t , -si[t] , 1 , n , 1); for(l = head[t] ; l ; l = next[l]) update(to[l] , si[to[l]] , 1 , n , 1); } } for(i = 1 ; i <= n ; i ++ ) printf("%d " , ans[i]); return 0; }
枚舉 $k$ 大值,單次 $O(n^2)$ 樹形揹包暴力,注意要用uint,卡卡常便可,沒什麼好說的。
#include <cstdio> #include <cstring> #include <algorithm> #define N 1675 #define mod 64123 using namespace std; typedef unsigned int ui; int a[N] , id[N] , head[N] , to[N << 1] , next[N << 1] , cnt , si[N] , last[N] , now; ui f[N][N]; bool cmp(int x , int y) {return a[x] == a[y] ? x <= y : a[x] < a[y];} inline void add(int x , int y) {to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;} void dfs(int x , int fa) { int i , j , k; for(i = last[x] ; i <= si[x] ; i ++ ) f[x][i] = 0; if(cmp(id[now] , x)) si[x] = last[x] = 1; else si[x] = last[x] = 0; f[x][si[x]] = 1; for(i = head[x] ; i ; i = next[i]) { if(to[i] != fa) { dfs(to[i] , x); for(j = si[x] ; j >= last[x] ; j -- ) for(k = si[to[i]] ; k >= last[to[i]] ; k -- ) f[x][j + k] = (f[x][j + k] + f[x][j] * f[to[i]][k]) % mod; si[x] += si[to[i]]; } } for(i = last[x] ; i <= si[x] ; i ++ ) f[0][i] = (f[0][i] + f[x][i]) % mod; } int main() { freopen("coat.in" , "r" , stdin); freopen("coat.out" , "w" , stdout); int n , k , w , i , x , y; ui ans = 0; scanf("%d%d%d" , &n , &k , &w); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , id[i] = i; for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x); sort(id + 1 , id + n + 1 , cmp); for(now = 1 ; now <= n ; now ++ ) { memset(f[0] , 0 , sizeof(f[0])); dfs(1 , 0); for(i = k ; i <= n ; i ++ ) ans = (ans + f[0][i] * (a[id[now]] - a[id[now - 1]])) % mod; } printf("%u\n" , ans); return 0; }