青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

(首先聲明一下,今年AHOI R1的題==JSOI R3 Day1的題)
【題解】
sport:
首先很容易證明,最優(yōu)方案必然是左邊都是-,右邊都是+(從樣例也可以看出來囧)……
因此問題轉(zhuǎn)化為了第幾次開始+,可以使得開始+的時(shí)候,目標(biāo)元素的位置最左……
注意到排隊(duì)的過程實(shí)際上是個(gè)冒泡……因此本題的關(guān)鍵在于發(fā)掘出冒泡的性質(zhì)囧……
設(shè)最初的序列為A[0..N-1],目標(biāo)元素為A[pos]。設(shè)S[0]為排在A[pos]之左的比A[pos]大的元素的個(gè)數(shù)(因?yàn)橐婚_始排在A[pos]之左的且<=A[pos]的元素,不管腫么搞都一直在目標(biāo)元素之左,不管它們了囧……),然后,考察所有一開始排在A[pos]之右的,比A[pos]小(注意是<A[pos],不是<=)的所有元素,設(shè)它們之間的間隔分別為S[1]、S[2]、S[3]……(具體見圖,其中S[1]為A[pos]和第一個(gè)比A[pos]小的元素之間的間隔)

然后來審視一下整個(gè)冒泡的過程。一開始,必然是將目標(biāo)元素左邊的一個(gè)比目標(biāo)元素大的元素移到右邊去,在目標(biāo)元素右邊它可能會(huì)停下來,但緊接著必然是一個(gè)值更大的元素繼續(xù)往右移,最終的效果等價(jià)于將目標(biāo)元素左邊的一個(gè)比目標(biāo)元素大的元素“移出去”了(即移到了最右邊的比目標(biāo)元素小的元素的右邊),也就是S[0]減了1,而S[1]、S[2]……都沒變,這個(gè)過程顯然只能持續(xù)S[0]次,目標(biāo)元素左邊比它大的元素就全部移出去,此時(shí)目標(biāo)元素到達(dá)了它“可能到達(dá)”的最左位置。
接著,目標(biāo)元素和右邊第一個(gè)比它小的元素(即圖中的A[i1])之間的,比目標(biāo)元素大的那些元素將被依次的移出去,也就是S[1]不斷減1,而S[2]及后面的都沒變。這一過程會(huì)持續(xù)S[1]次,目標(biāo)元素就和A[i1]靠在一起了(注意,在這個(gè)過程中,目標(biāo)元素的位置是不會(huì)變的)。
如果此時(shí)繼續(xù)冒泡,則目標(biāo)元素就會(huì)和A[i1]交換,右移一個(gè)位置,并且就從這次冒泡開始,S[2]不斷減1,減到0為止,接著目標(biāo)元素和A[i2]交換,右移一個(gè)位置,S[3]不斷減1……直到最后一個(gè)S[]值也減到0后,目標(biāo)元素到達(dá)它的目標(biāo)位置。
也就是,設(shè)“第i階段”為S[i]值減少的這個(gè)階段,則在第0階段,目標(biāo)元素會(huì)不斷左移,顯然不用+,第1階段,目標(biāo)元素不動(dòng),也不用+,但從第2階段開始,在每階段的第一次冒泡時(shí),目標(biāo)元素都會(huì)向右移一個(gè)位置。因此,開始+的時(shí)候,必然是第x(x>=2)階段的開始的那次。由于最多只能+ K次,因此可能的最左位置就是滿足N-1-∑(0<=j<x)S[j] <=K的最小的x值減2,加上一開始就在目標(biāo)元素之左的,且值不大于目標(biāo)元素的元素個(gè)數(shù)(它們必然在目標(biāo)元素之左)。注意特殊情況:x<2(此時(shí)當(dāng)成x=2處理),或者x不存在(全是-)。
因此,本題就是預(yù)處理求出所有S之后,掃一遍得出最小的x值就行了,O(N)。
當(dāng)然,二分答案+暴力判斷可以得50,有神犇說二分答案之后可以在O(N)時(shí)間內(nèi)判斷,從而O(NlogN)解決,我太弱了,完全搞不懂囧……(Orz!!)

mole:
首先,一個(gè)很重要的事實(shí)就是,“整個(gè)過程中左手所在的位置嚴(yán)格小于右手”其實(shí)是一個(gè)廢條件!!因?yàn)槿绻笥沂纸徊媪耍厝皇亲笫衷噲D去打靠右的一個(gè),而右手試圖去打靠左的一個(gè),此時(shí),讓它們交換,則兩只手移動(dòng)的距離都變小,方案仍然合法,且更優(yōu)(我太弱了,當(dāng)時(shí)就是在這里想抽了很久,以至于木有做這題……后來才知道這題很水……真悲劇!!!)
接下來就變成了一個(gè)全局統(tǒng)籌的問題,可以用網(wǎng)絡(luò)流解決:每個(gè)地鼠i拆成兩個(gè)點(diǎn):入點(diǎn)i'、出點(diǎn)i'',中間連一條容量為1(表示只能打一次),費(fèi)用為它的得分的邊,兩只手開始的位置也當(dāng)成有地鼠,只不過得分為0而已。如果某只手在打完第i個(gè)地鼠后能接著去打第j個(gè)地鼠,就連邊<i'', j'>,容量1,費(fèi)用0。s往表示兩只手開始的兩個(gè)點(diǎn)的入點(diǎn)連一條容量為1,費(fèi)用為0的邊,每個(gè)出點(diǎn)往T連一條容量為1,費(fèi)用為0的邊。求這個(gè)圖的最大費(fèi)用最大流即可。
當(dāng)然,用O(N3)的DP也可以得到至少60分,如果卡的好的話可能有80以上囧……

bus:
裸的數(shù)據(jù)結(jié)構(gòu)題,用一坨Splay Tree維護(hù)即可,唯一要注意的就是鏈可以翻轉(zhuǎn),因此要rev標(biāo)記……
還是不會(huì)搞的可以去做ZJOI2012 Day2的某題……
這題在數(shù)據(jù)結(jié)構(gòu)題中還是比較好寫的……值得吐槽的是它的對拍很難寫……本沙茶寫正解用了50min,寫對拍用了75min……
———————————————————————————————————————————————————
【總結(jié) && 一些閑扯】
(1)(Orz @sunzhouyi)
“要想滾粗:
0.仔細(xì)看錯(cuò)或者記錯(cuò)題。
1.選對不可做題。
2.思考坑爹題[鑒于‘坑爹’一詞在AH的特殊含義,建議這一點(diǎn)改為“思考廢條件怎么處理”]。
3.認(rèn)真寫自己不會(huì)的東西。
4.最后還不寫暴力分。”
本沙茶中了其中的三點(diǎn),因此悲劇了……
(2)熱烈慶祝今年的題目不再坑爹了!!!!!(因?yàn)橛玫氖荍SOI的題,bus還抄襲了ZJOI……)
(3)這次的題目……要么是難想、好寫(sport代碼只有1K多),要么是好想、較難寫,但還可以寫的完的(指bus,和BZOJ上最近的那些數(shù)據(jù)結(jié)構(gòu)相比真是太人道了……)
(4)要善于發(fā)掘題目的本質(zhì),特別是一些隱含的最優(yōu)性質(zhì)(比如mole的那個(gè)廢條件為什么廢);
(5)遇到想了很久想不出的題,一定要換一個(gè)方向去想,因?yàn)楹芸赡苁且婚_始的方向疵了;
(6)對于代碼量較大的題(如數(shù)據(jù)結(jié)構(gòu)題),到底寫不寫是要看情況的,靈活掌握;

一些閑扯:
(1)本沙茶所在的考場幾乎全是神犇,就我一個(gè)沙茶……于是被虐傻了……
(2)比賽時(shí)看到對面的一個(gè)人在喝“和其正”……瞬間嚇傻了……(話說腫么木有看到喝阿華田的囧……)
(3)昨天試機(jī)的時(shí)候,被Atbiter虐了半天,一開始腫么配置都是“找不到答案文件”……后來才發(fā)現(xiàn)Atbiter已經(jīng)改版了,players下面的第一層文件夾應(yīng)該是考試場數(shù)編號(Day1、Day2……);
(4)試機(jī)的時(shí)候發(fā)現(xiàn)鼠標(biāo)是壞的,后來才知道這個(gè)考場有6個(gè)鼠標(biāo)壞了,3個(gè)鍵盤壞了,2個(gè)系統(tǒng)時(shí)間顯示錯(cuò)誤……
(5)總之這次掛慘了,不過前30應(yīng)該能進(jìn),重點(diǎn)是Round2,加油!!我要復(fù)仇!!

posted @ 2013-05-18 17:38 Mato_No1 閱讀(1142) | 評論 (4)編輯 收藏

原題地址
這題真是太神犇了……可以讓人完全搞懂?dāng)?shù)論同余部分的全部內(nèi)容……

題解……由于虹貓大神已經(jīng)在空間里寫得很詳細(xì)了,所以就不腫么寫了囧……
主要說一下一些難想的和容易搞疵的地方:
(1)中國剩余定理的那個(gè)推論(多個(gè)同余方程的模數(shù)互質(zhì),則整個(gè)方程組在小于所有模數(shù)之積的范圍內(nèi)的解數(shù)等于各個(gè)方程解數(shù)之積)其實(shí)是很強(qiáng)大的,不光對線性同余方程有用,對這種非線性的同余方程也有用,只需要所有方程都滿足:若模數(shù)為MOD,則a是解當(dāng)且僅當(dāng)(a+MOD)是解……本題顯然滿足,因此,只要在按質(zhì)因數(shù)拆分后求出各個(gè)方程的解數(shù),再相乘即可(本沙茶就是這里木有想起來,結(jié)果看了虹貓的題解囧……);
(2)對于余數(shù)不為0且和模數(shù)不互質(zhì)的情況要特別注意(這個(gè)好像很多標(biāo)程都疵了,比如虹貓給的標(biāo)程,不過數(shù)據(jù)弱,讓它們過了囧),首先必須是余數(shù)含p(p為該方程模數(shù)的質(zhì)因數(shù))因子的個(gè)數(shù)j是a的倍數(shù)(也就是余數(shù)是p^a的倍數(shù))才能有解,然后,當(dāng)有解時(shí),轉(zhuǎn)化為解必須是p^(j/a)的倍數(shù)以及x/(p^(j/a))滿足一個(gè)模數(shù)指數(shù)為原來指數(shù)減j的方程,這里需要注意,這個(gè)新方程的解數(shù)乘以p^(j-j/a)才是原來方程的解數(shù)!!道理很簡單,因?yàn)槟?shù)除以了p^j,而x只除以了p^(j/a)……可以用一組數(shù)據(jù)檢驗(yàn):3 330750 6643012,結(jié)果是135而不是15;
(3)原根只能暴力求(不過最小原根都很小,1000以內(nèi)的所有質(zhì)數(shù)最小原根最大只有19……),但在求的時(shí)候有一個(gè)小的優(yōu)化:首先p的原根也是p的任意整數(shù)次方的原根,然后求p的原根時(shí),將(p-1)的非自身因數(shù)(預(yù)先求出)遞減排序,這樣可以比較快地排除不合法解;
(4)求逆元時(shí)一定要注意,如果得到的逆元是負(fù)數(shù),要轉(zhuǎn)化為正數(shù),另外要取模;
(5)BSGS的時(shí)候一定要注意去重,在保留重復(fù)元素的情況下即使使用另一種二分查找也會(huì)疵的;
(6)數(shù)組不要開小了;

代碼:
#include <iostream>
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
#include 
<math.h>
#include 
<algorithm>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
#define ll long long
const int MAXN = 110, MAXP = 50010, INF = ~0U >> 2;
int P_LEN, _P[MAXP + 1], P[MAXP + 1];
int A, B, M, n, DS[MAXN], DK[MAXN], R[MAXN], KR[MAXP], res;
struct sss {
    
int v, No;
    
bool operator< (sss s0) const {return v < s0.v || v == s0.v && No < s0.No;}
} Z[MAXP];
void prepare0()
{
    P_LEN 
= 0int v0;
    
for (int i=2; i<=MAXP; i++) {
        
if (!_P[i]) P[P_LEN++= _P[i] = i; v0 = _P[i] <= MAXP / i ? _P[i] : MAXP / i;
        
for (int j=0; j<P_LEN && P[j]<=v0; j++) _P[i * P[j]] = P[j];
    }
}
void prepare()
{
    n 
= 0int M0 = M;
    re(i, P_LEN) 
if (!(M0 % P[i])) {
        DS[n] 
= P[i]; DK[n] = 1; M0 /= P[i]; while (!(M0 % P[i])) {DK[n]++; M0 /= P[i];} n++;
        
if (M0 == 1break;
    }
    
if (M0 > 1) {DS[n] = M0; DK[n++= 1;}
    
int x;
    re(i, n) {
        x 
= 1; re(j, DK[i]) x *= DS[i];
        R[i] 
= B % x;
    }
}
ll pow0(ll a, 
int b, ll MOD)
{
    
if (b) {ll _ = pow0(a, b >> 1, MOD); _ = _ * _ % MOD; if (b & 1) _ = _ * a % MOD; return _;} else return 1;
}
void exgcd(int a, int b, int &x, int &y)
{
    
if (b) {
        
int _x, _y; exgcd(b, a % b, _x, _y);
        x 
= _y; y = _x - a / b * _y;
    } 
else {x = 1; y = 0;}
}
int gcd(int a, int b)
{
    
int r = 0while (b) {r = a % b; a = b; b = r;} return a;
}
void solve()
{
    
int x, y; res = 1;
    re(i, n) 
if (!R[i]) {
        
if (DK[i] < A) x = 1else x = (DK[i] - 1/ A + 1;
        re2(j, x, DK[i]) res 
*= DS[i];
    } 
else if (!(R[i] % DS[i])) {
        x 
= 0while (!(R[i] % DS[i])) {R[i] /= DS[i]; x++;}
        
if (x % A) {res = 0return;} else {
            DK[i] 
-= x; y = x / A;
            re2(j, y, x) res 
*= DS[i];
        }
    }
    
int phi, m0, m1, KR_len, _r, v0, _left, _right, _mid, T; bool FF;
    re(i, n) 
if (R[i]) {
        x 
= DS[i] - 1; KR_len = 0;
        
for (int j=2; j*j<=x; j++if (!(x % j)) {
            KR[KR_len
++= j;
            
if (j * j < x) KR[KR_len++= x / j;
        }
        KR[KR_len
++= 1;
        re2(j, 
2, DS[i]) {
            FF 
= 1;
            rre(k, KR_len) {
                _r 
= (int) pow0(j, KR[k], DS[i]);
                
if (_r == 1) {FF = 0break;}
            }
            
if (FF) {x = j; break;}
        }
        phi 
= DS[i] - 1; re2(j, 1, DK[i]) phi *= DS[i]; v0 = phi / (DS[i] - 1* DS[i];
        m0 
= (int) ceil(sqrt(phi) - 1e-10);
        Z[
0].v = 1; Z[0].No = 0; re2(j, 1, m0) {Z[j].v = (ll) Z[j - 1].v * x % v0; Z[j].No = j;}
        _r 
= (ll) Z[m0 - 1].v * x % v0; sort(Z, Z + m0);
        m1 
= 1; re2(j, 1, m0) if (Z[j].v > Z[j - 1].v) Z[m1++= Z[j];
        exgcd(_r, v0, x, y); 
if (x < 0) x += v0; y = R[i];
        re(j, m0) {
            _left 
= 0; _right = m1 - 1; T = -1;
            
while (_left <= _right) {
                _mid 
= _left + _right >> 1;
                
if (y == Z[_mid].v) {T = j * m0 + Z[_mid].No; break;}
                
else if (y < Z[_mid].v) _right = _mid - 1else _left = _mid + 1;
            }
            
if (T >= 0breakelse y = (ll) y * x % v0;
        }
        x 
= gcd(A, phi); if (T % x) {res = 0break;} else res *= x;
    }
}
int main()
{
    
int tests;
    scanf(
"%d"&tests);
    prepare0();
    re(testno, tests) {
        scanf(
"%d%d%d"&A, &B, &M); M += M + 1; B %= M;
        
if (!A) {
            
if (B == 1) res = M; else res = 0;
        } 
else {
            prepare();
            solve();
        }
        printf(
"%d\n", res);
    }
    
return 0;
}

posted @ 2013-03-15 19:24 Mato_No1 閱讀(1443) | 評論 (2)編輯 收藏

【1】BZOJ1713
F[i][j]=max{F[i1][j1] - (sA[i-1]-sA[i1])2 - (sB[j-1]-sB[j1])2} + A[i]*B[j], 0<=i1<i, 0<=j1<j
對這個(gè)式子進(jìn)行化簡:
F[i][j]=max{F[i1][j1] - sA[i1]2 + 2*sA[i-1]*sA[i1] - sB[j1]2 + 2*sB[j-1]*sB[j1]}+A[i]*B[j]-sA[i-1]2-sB[j-1]2
對于一維的情況,很容易處理——中間就是一條直線,然而這是二維的,對于這種2D/2D的DP方程,要優(yōu)化到O(N2)級別,需要兩步。
注意到?jīng)Q策式中除了F[i1][j1]外,其它部分都要么只與i1有關(guān),要么只與j1有關(guān)。因此,可以把階段i的各個(gè)狀態(tài)作為一個(gè)整體,在之前得出的各個(gè)F[i][j]中,對于相同的j,找到對于目前的i,最優(yōu)的那個(gè)決策——注意,對于相同的j1,里面所有與j1有關(guān)的東西都可以先不考慮了,只考慮(F[i1][j1] - sA[i1]2 + 2*sA[i-1]*sA[i1])對于目前i的最優(yōu)決策。這一步可以在這些直線形成的上凸殼中找到,且滿足決策單調(diào)性,可以用一個(gè)棧處理(斜率優(yōu)化)。然后,將這些最優(yōu)決策以j為自變量再組成一些直線,用棧維護(hù)它們的上凸殼,對于每個(gè)j,找到最優(yōu)值即可。
注意事項(xiàng):在棧中刪除直線的時(shí)候,如果之前的最優(yōu)決策是這個(gè)被刪掉的直線,則要將最優(yōu)決策先置為不存在,然后再插入新直線后設(shè)為新直線。另外,要特別注意平行的情況。

【2】LCIS
經(jīng)典問題,利用上面的分步優(yōu)化思想,很容易用線段樹得到一個(gè)O(N2logN)的做法。

【3】[SCOI2010]股票交易
F[i][j]=max{F[i-1][j], max{F[i-W-1][j-a]-A*a, F[i-W-1][j+b]+b*B}}, j<=maxP, 1<=a<=maxA, 1<=b<=maxB
注意對于相同的j,計(jì)算方法是一樣的,且是一條直線(由于有范圍所以其實(shí)是線段)。
所以,計(jì)算階段i時(shí),可以將(i-W-1)階段所有的決策當(dāng)成線段插入,這些線段的斜率都相等,因此比較好維護(hù),只需要判斷邊界即可。

注意,NOI2011的show雖然也符合對于相同的j計(jì)算方法一樣,但它就不能優(yōu)化,因?yàn)樗臎Q策是不連續(xù)且無規(guī)律的,沒有任何幾何性質(zhì)。因此,它只能用O(N3)的算法計(jì)算出所有狀態(tài)。

posted @ 2013-03-03 15:25 Mato_No1 閱讀(1032) | 評論 (0)編輯 收藏

     摘要: 原題地址寫了幾天終于寫出來了……(顯然,我太弱了,請各位神犇不要鄙視)在有加點(diǎn)的情況下,動(dòng)態(tài)地維護(hù)凸包,有以下兩種方法:<1>維護(hù)上、下凸殼(本沙茶采用的方法):凸包可以拆成上、下凸殼,對它們分別維護(hù)。兩個(gè)凸殼均按照下面定義的<關(guān)系(即先x增、再y增)排序,注意,兩個(gè)凸殼的兩端是相同的,均為整個(gè)凸包的最小點(diǎn)與最大點(diǎn),除兩端外,它們沒有公共定點(diǎn)。以上凸殼為例...  閱讀全文

posted @ 2013-02-28 18:29 Mato_No1 閱讀(2845) | 評論 (0)編輯 收藏

RT,
今天又優(yōu)化了一下JZPKIL,用上了各種無恥的手段,仍然無法干掉后兩個(gè)點(diǎn),并且BZOJ上的總時(shí)間50s也無法實(shí)現(xiàn)(后兩個(gè)點(diǎn)一個(gè)就要20s),
看來基于組合數(shù)的做法由于要枚舉因數(shù),確實(shí)不行……
(注:后兩個(gè)點(diǎn)是人工構(gòu)造的猥瑣數(shù)據(jù),所有的N都是若干個(gè)小質(zhì)數(shù)之積,因數(shù)個(gè)數(shù)都上千,有的甚至上萬……)

認(rèn)輸了……
Orz @sevenk

posted @ 2013-02-06 23:26 Mato_No1 閱讀(1215) | 評論 (1)編輯 收藏

又是一次WC……
本沙茶這半年來過得真是頹廢啊囧(雖然比上賽季同期好一些)……實(shí)力雖然有所提高,但比起別人來說太不值得一提了……
本次WC又不知道要被多少人(神犇或一般人)虐了……

三個(gè)愿望:
(1)能聽懂盡可能多的知識點(diǎn),最好能將自己以前搞不懂的那些都搞懂囧……
(2)能認(rèn)識盡可能多的神犇(包括集訓(xùn)隊(duì)的和本屆的),最好能找到一個(gè)人以后共勉,這樣就不會(huì)再頹廢了囧……
(3)明年還能去WC囧(nimendongde)……

posted @ 2013-01-23 22:37 Mato_No1 閱讀(391) | 評論 (0)編輯 收藏

     摘要: 【先祝賀一下@Jollwish神犇進(jìn)入CMO國家集訓(xùn)隊(duì)……合肥OI人總算出了個(gè)國家集訓(xùn)隊(duì)員(雖然不是OI的)……】最近捉了兩道猥瑣題……都是有關(guān)圖中刪去某邊后的最短路徑的問題……核心思想幾乎相同……但是,它們很明顯是綜合題,代碼量太大了(與NOIP2012的drive和block...  閱讀全文

posted @ 2013-01-19 16:49 Mato_No1 閱讀(2675) | 評論 (0)編輯 收藏

原題地址
2013年第一題……紀(jì)念一下……

設(shè)F[i][j]表示坐i次電梯到達(dá)房間j,最多能到幾樓,則有
F[i][j]=max{F[i-1][k]+W[k][j]}, 0<=k<n;
這里W[k][j]要注意,如果不存在從k到j(luò)的電梯,W[k][j]應(yīng)設(shè)為-INF。
這個(gè)方程顯然是可以用矩陣乘法來優(yōu)化的。
然后,問題就是求出最小的i使得F[i]的狀態(tài)中有值>=M的,這個(gè)可以二分(每次看當(dāng)前解與W的(2^K-1)次方的運(yùn)算結(jié)果,若有解則實(shí)際不進(jìn)行這次運(yùn)算,否則與W的2^K次方運(yùn)算)……總時(shí)間復(fù)雜度是O(n3logM)的,對于本題可能要進(jìn)行一些常數(shù)優(yōu)化才能過(20個(gè)點(diǎn),每個(gè)點(diǎn)5個(gè)數(shù)據(jù),相當(dāng)于100個(gè)點(diǎn),時(shí)限只有40s),反正本沙茶是卡線過的。

但是,本題有一個(gè)細(xì)節(jié)很重要,必須要說一下(因?yàn)楸旧巢柙谶@里卡了1h+)……那就是溢出問題……
F[i][j]的值是有可能超過long long的范圍的,然而如果硬加高精度的話穩(wěn)T,這時(shí),在進(jìn)行矩陣乘法(實(shí)際是加法)的時(shí)候,需要特判一下,如果這個(gè)和超過了INF(INF是~0Ull>>2,>1018),就取INF。這樣可能會(huì)破壞結(jié)合律,但是木有事,因?yàn)槿魞蓚€(gè)加數(shù)都是非負(fù)數(shù),則不會(huì)破壞,若有負(fù)數(shù),則一定表示無解(-INF),這個(gè)特判一下就行了(若兩個(gè)加數(shù)之中有負(fù)數(shù),則結(jié)果取-INF)。

代碼:
#include <iostream>
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
#define re2(i, l, r) for (int i=l; i<r; i++)
#define re3(i, l, r) for (int i=l; i<=r; i++)
#define rre(i, n) for (int i=n-1; i>=0; i--)
#define rre1(i, n) for (int i=n; i>0; i--)
#define rre2(i, r, l) for (int i=r-1; i>=l; i--)
#define rre3(i, r, l) for (int i=r; i>=l; i--)
#define ll long long
const int MAXN = 110, MAXLEN = 61;
const ll INF = ~0Ull >> 2;
int n;
ll M, A[MAXLEN][MAXN][MAXN], W0[MAXN][MAXN], _[MAXN][MAXN], res;
void mult(ll A0[][MAXN], ll B0[][MAXN])
{
    re(i, n) re(j, n) _[i][j] 
= -INF; ll __;
    re(i, n) re(j, n) re(k, n) 
if (A0[i][k] >= 0 && B0[k][j] >= 0) {
        __ 
= A0[i][k] + B0[k][j];
        
if (__ > INF) __ = INF;
        
if (__ > _[i][j]) _[i][j] = __;
    }
}
void prepare()
{
    re2(i, 
1, MAXLEN) {
        mult(A[i 
- 1], A[i - 1]);
        re(j, n) re(k, n) A[i][j][k] 
= _[j][k];
        mult(A[i], A[
0]);
        re(j, n) re(k, n) A[i][j][k] 
= _[j][k];
    }
}
void solve()
{
    re(i, n) re(j, n) 
if (i == j) W0[i][j] = 0else W0[i][j] = -INF; bool FF; res = 0;
    rre(i, MAXLEN) {
        FF 
= 0; re(j, n) if (A[i][0][j] >= M) {FF = 1break;}
        
if (FF) continue;
        mult(W0, A[i]);
        FF 
= 0; re(j, n) if (_[0][j] >= M) {FF = 1break;}
        
if (!FF) {
            re(j, n) re(k, n) W0[j][k] 
= _[j][k];
            mult(W0, A[
0]);
            re(j, n) re(k, n) W0[j][k] 
= _[j][k];
            res 
+= 2ll << i;
        }
    }
    FF 
= 0; re(i, n) if (W0[0][i] >= M) {FF = 1break;}
    
if (!FF) res++;
}
int main()
{
    
int tests;
    scanf(
"%d"&tests);
    re(testno, tests) {
        cin 
>> n >> M;
        re(i, n) re(j, n) {scanf(
"%lld"&A[0][i][j]); if (!A[0][i][j]) A[0][i][j] = -INF;}
        prepare();
        solve();
        cout 
<< res << endl;
    }
    
return 0;
}

posted @ 2013-01-01 15:39 Mato_No1 閱讀(546) | 評論 (0)編輯 收藏

在線段樹中,一般都不需要刻意保存其左右子結(jié)點(diǎn)的下標(biāo),而直接由其本身的下標(biāo)導(dǎo)出,傳統(tǒng)的寫法是:
根結(jié)點(diǎn):1
A的左子結(jié)點(diǎn):2A(寫成A<<1)
A的右子結(jié)點(diǎn):2A+1(寫成(A<<1)+1)
這種表示法可以表示出整棵線段樹,因?yàn)椋?br />(1)每個(gè)結(jié)點(diǎn)的子結(jié)點(diǎn)的下標(biāo)都比它大,這樣就不會(huì)出現(xiàn)環(huán);
(2)每個(gè)結(jié)點(diǎn)的父結(jié)點(diǎn)都是唯一的(其本身下標(biāo)整除2);
但是,這種表示法有一個(gè)弱點(diǎn):結(jié)點(diǎn)的下標(biāo)是有可能超過2N的,但不會(huì)超過4N,因此,為了表示出跨度為N的線段,我們需要開4N的空間,然而,其中只有2N-1個(gè)位置是有用的(因?yàn)楸硎究缍葹镹的線段的線段樹共有(2N-1)個(gè)結(jié)點(diǎn)),這樣,就有一半的空間被浪費(fèi)。尤其是這種線段樹推廣到多維的時(shí)候——K維線段樹就只有1/2K的位置是有用的,空間利用率非常低。在某些卡空間的場合,它就囧掉了。

那么,有木有好一點(diǎn)的寫法呢?最好能使空間利用率達(dá)到100%——也就是所有結(jié)點(diǎn)的下標(biāo)剛好就是1~(2N-1)!!(0號結(jié)點(diǎn)一般作為“哨兵”,不被占用)
并且,這種寫法要保證僅僅由結(jié)點(diǎn)的下標(biāo)和它表示的線段的左右端點(diǎn)(因?yàn)樵诒闅v線段時(shí),下標(biāo)和左右端點(diǎn)基本上都是同時(shí)知道的),就能得出其子結(jié)點(diǎn)的下標(biāo),而不需要借助額外的東東(最好mid都不需要算)。
這種寫法就是——直接將每個(gè)結(jié)點(diǎn)的DFS遍歷次序當(dāng)做它的下標(biāo)!!
比如,跨度為6的線段樹:

容易發(fā)現(xiàn),根結(jié)點(diǎn)下標(biāo)為1,下標(biāo)為A的結(jié)點(diǎn)的左子結(jié)點(diǎn)下標(biāo)為(A+1),右子結(jié)點(diǎn)下標(biāo)為A+SZ(A.L)+1,其中SZ(A.L)為A的左子樹大小。
若A的左右端點(diǎn)為l、r,mid=(l+r)/2(下取整),則A的左子樹所表示的線段為[l, mid],所以SZ(A.L)=(mid-l+1)*2-1=(mid-l)*2+1=((r-l-1)/2(上取整))*2+1
這樣,A的右子結(jié)點(diǎn)下標(biāo)就是A+((r-l+1)/2(上取整))*2,也就是A加上大于(r-l)的最小的偶數(shù)
寫在代碼里就是:
int mid=l+r>>1;
opr(l, mid, A
+1);
opr(mid
+1, r, (r-l&1?A+r-l+1:A+r-l+2));
或者,借助位運(yùn)算,可以免去條件判斷:
int mid=l+r>>1;
opr(l, mid, A
+1);
opr(mid
+1, r, A+r-l+2-((r^l)&1));
經(jīng)測試,后者(使用位運(yùn)算的)雖然總的運(yùn)算次數(shù)多于前者(使用條件判斷的),但后者比前者快一點(diǎn)點(diǎn),其原因可能與C語言中的條件運(yùn)算符速度較慢有關(guān);

這樣,我們就成功地將線段樹下標(biāo)的空間利用率提高到了100%!!以后只需要開2N空間就行了囧……
與傳統(tǒng)表示法相比,這種新式表示法雖然可以節(jié)省空間,但時(shí)間消耗要更大一些(時(shí)間和空間總是矛盾的囧……),因?yàn)樗谡矣易咏Y(jié)點(diǎn)的時(shí)候需要較多的運(yùn)算。平均起來,新式表示法比傳統(tǒng)表示法要慢10~15%,對于某些坑爹的數(shù)據(jù)(對右子結(jié)點(diǎn)調(diào)用比較多的那種)可能慢得更多。此外,在下放標(biāo)記的時(shí)候,傳統(tǒng)表示法只需要知道結(jié)點(diǎn)下標(biāo)就行了,而新式表示法必須同時(shí)知道結(jié)點(diǎn)的左右端點(diǎn),這樣在dm中就需要傳遞三個(gè)參數(shù),從而要慢一些,當(dāng)然,我們可以不用dm,直接在操作里面寫標(biāo)記下放。

posted @ 2012-12-01 12:11 Mato_No1 閱讀(3405) | 評論 (2)編輯 收藏

原題地址
本沙茶去年曾經(jīng)用雙線段樹的方法捉了這題(詳見這里),最近重新審視這題發(fā)現(xiàn),借助平衡樹,可以得到更簡單的方法。

題目大意:
有一個(gè)長度為N的內(nèi)存條,每個(gè)位置的狀態(tài)有占用和不占用兩種,有4種操作:
(1)Reset:清空所有內(nèi)存(即將所有位置的狀態(tài)改為不占用,刪除所有內(nèi)存塊);
(2)New x:申請一個(gè)新的內(nèi)存塊,即找到一個(gè)長度為x的連續(xù)不占用位置區(qū)間,將它們標(biāo)記為占用,若有多個(gè)這樣的區(qū)間,取最左邊的,若木有輸出Reject New;
(3)Free x:在已申請的內(nèi)存塊中,找到包含位置x的并釋放(將該內(nèi)存塊刪除,同時(shí)其占用的所有位置改為不占用),若木有內(nèi)存塊包含位置x,則輸出Reject Free;
(4)Get x:找出已申請的內(nèi)存塊中,左起第x個(gè),并輸出其左端點(diǎn);若已申請的內(nèi)存塊數(shù)目不足x個(gè),則輸出Reject Get。

可以發(fā)現(xiàn),每個(gè)已經(jīng)申請的內(nèi)存塊盡管代表一段區(qū)間,但仍然是獨(dú)立的單位,因此,可以把內(nèi)存塊當(dāng)成結(jié)點(diǎn),用平衡樹維護(hù)(關(guān)鍵字為內(nèi)存塊的左端點(diǎn)位置),New操作中內(nèi)存塊的插入與Free操作中內(nèi)存塊的刪除均在此平衡樹內(nèi)進(jìn)行,Reset操作只需要將整棵樹銷毀即可。
問題是,在New操作中,需要找到一個(gè)長度為x的連續(xù)不占用區(qū)間,而連續(xù)的不占用區(qū)間并不是獨(dú)立的單位,因此需要使用線段樹維護(hù)。在線段樹中,需要維護(hù)<1>結(jié)點(diǎn)區(qū)間內(nèi)最長連續(xù)不占用塊的長度;<2>結(jié)點(diǎn)區(qū)間左端、右端連續(xù)不占用塊的長度(否則無法維護(hù)<1>);同時(shí),由于在New操作中需要區(qū)間整體改占用,F(xiàn)ree操作中又需要區(qū)間整體改不占用,所以應(yīng)當(dāng)支持整體改值的標(biāo)記,對于Reset操作,只需要全部位置改不占用即可(不能重新建樹!!);

這樣,利用一棵平衡樹加一棵線段樹,就可以得到一個(gè)很簡單的方法了(代碼量是雙平衡樹或雙線段樹的一半左右);

這題的啟示是,在解決數(shù)據(jù)結(jié)構(gòu)統(tǒng)計(jì)類題的時(shí)候,到底選用什么樣的數(shù)據(jù)結(jié)構(gòu),是有講究的,因?yàn)樗鼘⒅苯佑绊懙骄幊虖?fù)雜度。一般來說,線段樹比平衡樹好寫,但是對本題而言,雙線段樹反而不如平衡樹加線段樹好寫,這是因?yàn)閷τ趦?nèi)存塊使用平衡樹維護(hù)比使用線段樹維護(hù)更好。在以后做這種題的時(shí)候,要多想一下,找到簡便方法。

posted @ 2012-11-25 14:54 Mato_No1 閱讀(673) | 評論 (0)編輯 收藏

僅列出標(biāo)題
共12頁: 1 2 3 4 5 6 7 8 9 Last 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美色区777第一页| 亚洲欧洲一级| 亚洲国产成人精品久久久国产成人一区 | 欧美成人精品| 亚洲欧美一区二区激情| 欧美一区观看| 免费的成人av| 欧美日韩免费在线| 欧美午夜精品一区| 国产曰批免费观看久久久| 精品成人一区| 99精品热6080yy久久| 午夜精品亚洲| 欧美国产视频日韩| 亚洲视频免费| 裸体丰满少妇做受久久99精品| 欧美精品播放| 激情另类综合| 亚洲女人天堂av| 午夜一区二区三区在线观看| 久久精品99久久香蕉国产色戒| 久久综合色播五月| 99国产精品| 久久久精品动漫| 欧美日韩一卡二卡| 亚洲国产成人久久综合一区| 性欧美大战久久久久久久久| 欧美成人一品| 午夜精品999| 欧美日韩国产一区二区| 一区二区三区在线免费播放| 亚洲午夜91| 欧美大片免费| 性欧美精品高清| 欧美视频免费在线观看| 亚洲国产精品成人久久综合一区| 午夜伦欧美伦电影理论片| 亚洲日韩欧美视频| 免费看的黄色欧美网站| 国内成人精品一区| 亚洲欧美一区二区精品久久久| 欧美激情亚洲视频| 久久网站免费| 一区二区视频在线观看| 久久精品一区二区三区不卡| 亚洲欧美日韩在线不卡| 国产精品你懂的在线| 亚洲调教视频在线观看| 亚洲人成欧美中文字幕| 欧美大片va欧美在线播放| 在线观看欧美日韩| 久久精品亚洲国产奇米99| 亚洲视频在线播放| 欧美日韩一区二区在线观看| 日韩午夜在线电影| 亚洲国产福利在线| 欧美暴力喷水在线| 日韩视频二区| 亚洲精选大片| 国产精品jizz在线观看美国| 99视频精品| 一区二区电影免费观看| 国产精品久久九九| 亚洲欧美激情一区| 亚洲欧美国产日韩天堂区| 国产精品免费在线| 久久www成人_看片免费不卡| 校园春色综合网| 影音先锋中文字幕一区| 欧美成人一区二区| 欧美欧美全黄| 亚洲欧美日韩一区二区三区在线| 亚洲伊人伊色伊影伊综合网| 国产日韩精品视频一区二区三区| 久久精品一二三| 美女视频一区免费观看| 夜夜嗨av色一区二区不卡| 亚洲久久在线| 午夜亚洲影视| 久久九九热免费视频| 影音先锋欧美精品| 亚洲高清久久网| 欧美日韩www| 午夜视频精品| 久久婷婷蜜乳一本欲蜜臀| 亚洲黄色性网站| 亚洲精品永久免费| 国产一区二区精品久久| 亚洲大片精品永久免费| 国产精品久久久久999| 久久米奇亚洲| 欧美日韩1234| 久久综合久久综合九色| 欧美精品一区二区蜜臀亚洲| 亚洲女同性videos| 久久婷婷丁香| 小处雏高清一区二区三区 | 久久久精品动漫| 一区二区日本视频| 久久精品盗摄| 亚洲免费在线| 欧美成人精品在线观看| 久久精品国产一区二区三区免费看 | 欧美一区二区三区视频在线观看| 国产亚洲美州欧州综合国| 亚洲高清一区二区三区| 国产日韩一区二区三区在线播放| 亚洲电影第1页| 国产在线高清精品| 国产精品99久久久久久有的能看| 一区一区视频| 午夜精品久久久久久久99樱桃| 亚洲免费av片| 久久久天天操| 久久久噜噜噜久久| 国产精品久久毛片a| 亚洲黄色成人| 亚洲高清在线播放| 久久激情五月激情| 欧美一区二区三区在线观看| 欧美三级视频在线| 亚洲精品免费在线观看| 亚洲欧洲日韩女同| 老司机久久99久久精品播放免费 | 亚洲韩国一区二区三区| 樱桃成人精品视频在线播放| 久久黄金**| 久久久99国产精品免费| 国产日韩欧美亚洲一区| 亚洲欧美视频| 久久精品国产免费观看| 国产手机视频精品| 香蕉成人伊视频在线观看| 欧美一级久久久| 国产日韩欧美成人| 久久爱另类一区二区小说| 亚洲精品欧美激情| 久久精品免视看| 国产欧美在线观看一区| 亚洲欧美日韩成人| 性色一区二区| 国产一区二区三区视频在线观看| 亚洲免费一级电影| 久久久久久免费| 精品av久久707| 美国成人直播| 亚洲青涩在线| 亚洲综合色激情五月| 国产伦精品一区| 久久国产综合精品| 欧美韩日视频| 亚洲亚洲精品在线观看| 国产精品入口66mio| 欧美一区二区在线视频| 欧美韩日视频| 亚洲天堂网站在线观看视频| 国产欧美欧洲在线观看| 久久亚洲综合| 99精品视频免费观看视频| 久久国产欧美日韩精品| 亚洲电影视频在线| 欧美日韩一区二区三区四区五区| 亚洲在线1234| 欧美国产日韩精品| 午夜在线成人av| 亚洲国产毛片完整版| 欧美日韩中文字幕日韩欧美| 性欧美暴力猛交69hd| 欧美激情亚洲激情| 午夜久久tv| 91久久在线视频| 国产毛片一区二区| 欧美高清在线精品一区| 亚洲男女自偷自拍图片另类| 欧美成人午夜77777| 亚洲欧美日韩天堂一区二区| 亚洲国产精品123| 国产精品免费视频xxxx| 蜜桃av噜噜一区| 欧美亚洲免费高清在线观看| 亚洲人成在线观看一区二区 | 最新日韩欧美| 久久激情中文| av成人黄色| 亚洲国产激情| 国产有码一区二区| 国产精品久久久久久久久久ktv| 久久中文字幕一区| 欧美一级大片在线观看| aa成人免费视频| 欧美激情亚洲国产| 久久婷婷丁香| 久久成人国产| 香蕉久久精品日日躁夜夜躁| 亚洲最新视频在线播放| 亚洲国产日韩一级| 伊人久久婷婷| 黄色成人91| 国产综合自拍| 国产亚洲一区二区在线观看|