上來粘6個圖皮一下。(之後粘排行榜是否是都應該粘兩份啊。。。文件出入的確挺難受的)數組
話說最近RP爲何會這麼高啊???我幹什麼好事了???不知道。ide
此次考試的題挺有水準的,可是個人分數挺沒水準的。函數
T1打表找規律。嚴格來講不是打表找規律,是看樣例找規律而後手模一個表「驗證」了規律。優化
先作的T2簡單dp這個沒的說,數據範圍出到$10^{100}$複雜度也能接受(可是要寫高精了),出題人可能把T2弄成送分題了。spa
但是都不用矩陣快速冪,因此就這麼水過了。excel
T3的話出題人想複雜了。(?)code
拿二維線段樹能作複雜度也沒毛病,那麼爲何要分那麼多類討論呢?blog
因此說我仍是沒什麼水準。騙分能力卻是不錯。(雖然說這個騙分好像挺有臉的。。)遞歸
並且T3好像過不去對拍,在n超過1000的時候大概每2400組數據錯一個(在值域很小的時候),多是暴力掛了?遊戲
固然對拍讓我發現了一處錯誤從WA5裏拯救了我。
也不知道這樣的RP能維持到何時吧。。。
記得數組開大!!!不爆內存上限還不會算的時候爲何不開大一點呢?
丟了個AK。但不是很難過。這要是平時可能又要跳起來了吧2333
T1:小盆友的遊戲
要聽一下找規律的過程嗎?證實的話仍是找$LNC$或者是看題解吧。
題解裏都說了這是打表找規律題那麼爲何不打表呢?
首先看樣例,6個?出題人這麼好?
其實就提醒了我這須要找規律。
而後根據部分分和前4個樣例直接拿下50分。
而後看第5個,相較於第二個,它多了一個跟班,答案少了1。
而後看第6個,相較於第三個,它多了兩個跟班,答案少了3。
根據1->1和2->3,那麼猜想一下數列,要麼是1/3/5/7要麼是1/3/7/15。
直覺讓咱們選擇後者,由於後者就是前50分部分分的式子!(有小變化,指數少了1)
可是這樣很不嚴謹。因此首先咱們把前4個樣例代入後來發現的式子,發現知足規律。
而後把n=4的4種狀況所有都畫出來手解方程,發現4種狀態都知足。
(若是你還不放心,能夠像cbx同樣把n=5的6中狀況也來一遍,可是花費的時間可能比較長)
其實我也不是這麼不正經,我嘗試dp來着,可是沒作出來,發現沒有搜索的部分分,因而就認爲這是一個結論題。
指望得分:50分。
1 #include<cstdio> 2 #define mod 1000000007 3 int cnt[100005],n,ans,pw[100005]; 4 int main(){ 5 freopen("game.in","r",stdin); 6 freopen("game.out","w",stdout); 7 scanf("%d",&n); 8 for(int i=1,x;i<=n;++i)scanf("%d",&x),cnt[x>0?x:0]++; 9 for(int i=1;i<=n;++i)pw[i]=((pw[i-1]<<1)+1)%mod; 10 ans=pw[n-1]; 11 for(int i=1;i<=n;++i)ans=(ans-pw[cnt[i]]+mod)%mod; 12 printf("%d\n",ans); 13 }
T2:花
沒有矩陣快速冪的矩陣快速冪優化dp題。
狀態只有:1連擊,2連擊,3連擊,以前3連擊過而如今只有1連擊,以前3連擊過而如今有2連擊。以及已經非法的狀態。
1 #include<cstdio> 2 #define mod 1000000007 3 long long dp[6][100005],S,N; 4 int main(){ 5 freopen("flower.in","r",stdin); 6 freopen("flower.out","w",stdout); 7 int t;scanf("%d",&t); 8 while(t--){ 9 scanf("%lld%lld",&N,&S);S--; 10 dp[1][1]=S+1; 11 for(int i=2;i<=N;++i) 12 dp[1][i]=(dp[1][i-1]+dp[2][i-1])*S%mod, 13 dp[2][i]=dp[1][i-1], 14 dp[3][i]=dp[2][i-1], 15 dp[4][i]=(dp[3][i-1]+dp[4][i-1]+dp[5][i-1])*S%mod, 16 dp[5][i]=dp[4][i-1]; 17 printf("%lld\n",(dp[3][N]+dp[4][N]+dp[5][N])%mod); 18 } 19 }
T3:表格
強烈呼籲這道題提交以前檢查文件!一卡3分鐘!!!
update太多了因而直接說在前面:個人時空複雜度都是常數較小的$O(n^2)$。(暴力碾標算2333怪不得開了8s)
因此我是考場上水過的。正在看正解。
時空複雜度都是$O(nlog^2n)$的與正解一致。可是空間複雜度常數很大,時間複雜度的常數較小。
update:空間複雜度是錯誤的!空間複雜度爲$O(16n^2)$,因此下文的剪枝頗有必要(由於是動態開點因此剪枝能夠節約內存)
再update:空間複雜度沒那麼爛。由於每次查詢至多經歷$O(log^23n)$個節點因此n次操做的話總的空間最大也就$O(nlog^2n)$
可是其實$O(nlog^23n)$也不知足要求,因此仍是須要剪枝。
其實能夠在update函數執行時進行空間回收,可是不必。。。
再再update:QAQ時間複雜度又被hack了。$O(n)$的。。。會被長條卡掉。。。因此總的時空複雜度都是$O(n^2)$
固然若是你打的是動態開點樹套樹就能夠解決這個問題。(好像也被hack了)
因此我最慢的點也才跑0.7s可是我數組沒開夠
首先說明二維線段樹與KD-tree的不一樣:KD-tree基於讀入的序列,而線段樹基於值域。
KD-tree在不少狀況下都要想兩個兒子都要遞歸,而線段樹向兩個兒子都要遞歸的狀況最多隻會出現$log$次。
考慮一維的線段樹,你查詢的過程中通過的節點數一共有$log$個。
而二維的線段樹兩維互不干擾,這樣的話它所通過的節點的控制區間就是兩個一維線段樹的區間自由組合,最差是$log^2$個。
因此複雜度是正確的。
作法,就是時光倒流(題目中的「Crtl+Z」有必定提示意義)。而後發現你的操做就是:
1。查找當前區間內是否還有空位置,若是有,那麼ans+1。
2。把區間內全部位置設置爲非空。
區間查詢區間修改,不難想到線段樹。
爲了保證時空複雜度,須要離散化。
update操做就是若是兩個兒子中都沒有空位,那麼你的控制區間就也沒有空位了。
這樣的話會出現一個問題:離散化以後兩個兒子並不是緊密相鄰的。
因此在離散化的時候須要加入原右端點+1來表示它是緊密相鄰的。
而後就沒了。代碼真的好寫線段樹才和離散化通常長。
由於空間複雜度很高,因此須要動態開點。(不開行不行我也不知道)
它和KD-tree類似的一點就是要橫着切一刀豎着切一刀這麼交替的分下去。
爲何不能一直豎着分,分到所須要的節點再一直橫着切呢?
由於這樣的話很差合併子樹信息。其實不須要合併,可是合併以後至關與剪枝。
和四分樹仍是不太同樣的。好像網上有混淆二者概念的。
無論了,就當是我本身yy的吧。我這好像的確不叫二維線段樹。
而網上說的二維線段樹/四分樹的單次操做複雜度最差是$O(n)$的。。。
那麼你能夠管我打的這個樹叫Dee樹。嗯。(因此Dee樹就是TLE+MLE樹啦)
大家能夠叫我B哥。
——By Rockstar in 2018.9
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 int xa[100005],xb[100005],ya[100005],yb[100005],x[300005],y[300005],X,Y,n; 5 int qxl,qxr,qyl,qyr,lc[50000005],rc[50000005],ans=1,res,cnt,rt;char nt[50000005],u[100005]; 6 void modify(int &p,int cxl,int cxr,int cyl,int cyr,int opt){ 7 if(!p)p=++cnt; 8 if(nt[p])return; 9 if(qxl<=cxl&&cxr<=qxr&&qyl<=cyl&&cyr<=qyr)return nt[p]=1,ans+=res,res=0,(void)0; 10 if(opt){int mid=cxl+cxr>>1; 11 if(qxl<=mid)modify(lc[p],cxl,mid,cyl,cyr,0); 12 if(qxr>mid)modify(rc[p],mid+1,cxr,cyl,cyr,0); 13 }else{int mid=cyl+cyr>>1; 14 if(qyl<=mid)modify(lc[p],cxl,cxr,cyl,mid,1); 15 if(qyr>mid)modify(rc[p],cxl,cxr,mid+1,cyr,1); 16 }nt[p]=nt[lc[p]]&nt[rc[p]]; 17 } 18 int main(){ 19 freopen("excel.in","r",stdin); 20 freopen("excel.out","w",stdout); 21 scanf("%d",&n); 22 for(int i=1;i<=n;++i)scanf("%d%d%d%d",&xa[i],&ya[i],&xb[i],&yb[i]),xb[i]--,yb[i]--; 23 for(int i=1;i<=n;++i)x[i]=xa[i],x[i+n]=xb[i],x[i+n+n]=xb[i]+1,y[i]=ya[i],y[i+n]=yb[i],y[i+n+n]=yb[i]+1; 24 sort(x+1,x+1+n+n+n);sort(y+1,y+1+n+n+n); 25 X=unique(x+1,x+1+n+n+n)-x;Y=unique(y+1,y+1+n+n+n)-y; 26 for(int i=1;i<=n;++i)xa[i]=lower_bound(x+1,x+X,xa[i])-x,xb[i]=lower_bound(x+1,x+X,xb[i])-x; 27 for(int i=1;i<=n;++i)ya[i]=lower_bound(y+1,y+Y,ya[i])-y,yb[i]=lower_bound(y+1,y+Y,yb[i])-y; 28 for(int i=n;i;--i)qxl=xa[i],qxr=xb[i],qyl=ya[i],qyr=yb[i],res=1,modify(rt,1,X,1,Y,1); 29 printf("%d\n",ans); 30 }