北航校賽的一道題。。。
看到資料量就直接想到線段樹實現了,但是區間修改的操作不是線性關係,而是對區間內的每個數進行平方,那就需要對線段樹的節點進行類似於一種狀態壓縮的處理了。
因為結果是要對61求餘的,所以一開始想到的就是每個節點儲存60個值,分別代表對應數字在改區間內出現的次數,雖然空間複雜度勉強過的去,但是時間複雜度就難看了。。。。(囧,乙個節點要計算60次跪了)然後就想到優化一下,如果該節點的區間範圍小於61,就直接在此截止,下面直接就是個線性表,相當於線段樹砍掉下面的一部分,補了個線性表,那麼原來的線段樹層數就變成log2(100000/61)≈11層,加一層線性表那麼一次操作就是12*60=720次,乘個100000就是7200w,雖然題目時限8000ms,但這只是一顆10w節點的樹的處理時間。。。所以還是跪。。。
然後就尋思著開始找規律,直接把1~60所有的值都迴圈處理一遍,其中存在4個環,3個環的長度為4,1個環的長度為2,(看了別人的題解才想到費馬小定理可以直接得到6次平方操作==2次平方操作的結論【一口老血都噴在螢幕上】,數論沒學好=.=)那就是任意乙個數進行2次平方後就會進入乙個4長度或者2長度的迴圈節中,那麼對於每個節點只要儲存6種情況(2種+4種(迴圈)的sum就可以了,對於較大的延遲標記lazy的處理是先減乙個2再對迴圈節4求餘,然後把2加回來,這樣lazy就減小了。於是乎。。更新的問題就解決了。
#include const int mod = 61;
const int maxm = 110000;
const int size = 6;
int l,r;
struct p
} }void build(int left,int right,int pos)
int query(int left,int right,int pos)
void updata(int left,int right,int pos)
pushdown(pos);
int mid=(left+right)>>1;
if(l<=mid)updata(left,mid,pos<<1);
if(r>mid)updata(mid+1,right,pos<<1|1);
pushup(pos);
}}tree;
int main()
else}}}
中間把&運算的優先順序記錯了wa了好幾發。。 臥槽這遊戲簡直難玩 C語言 再也不寫排序演算法
在c語言乙個小專案裡面,大多數情況我們都是選擇自己造車輪,比如需要自己寫乙個排序演算法或者鍊錶,這樣的過程在學習的時候動手是充滿意義的,但是到了大專案之中,用標準庫和別人封裝好的演算法不香嗎?倘若蓋一棟樓之前,連每乙個磚塊都需要我們挖土燒磚,那麼這是多麼可怕巨大的工程量。所屬標準庫stdlib.h ...
我再也不擠公交上學了
來了乙個月了,各方面感覺還都不錯,悲劇的是第一天上課就遲到了 巨無語。沒用的話不多說,說說自己這乙個月來總結的東西。首先是練習量,可能有人會感覺練習量很大,實際上我也這麼覺得,但聰明的人會偷懶。首先是要挖掘練習的內在含義,練習為了記住知識點,所以我在練習以前都會總結一下需要用到的知識點,大家也可以試...
我再也不擠公交上學了
來了乙個月了,各方面感覺還都不錯,悲劇的是第一天上課就遲到了 巨無語。沒用的話不多說,說說自己這乙個月來總結的東西。首先是練習量,可能有人會感覺練習量很大,實際上我也這麼覺得,但聰明的人會偷懶。首先是要挖掘練習的內在含義,練習為了記住知識點,所以我在練習以前都會總結一下需要用到的知識點,大家也可以試...