日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SGU 187 - Twist and whirl -- want to cheat

發布時間:2024/7/19 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SGU 187 - Twist and whirl -- want to cheat 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原題地址:http://acm.sgu.ru/problem.php?contest=0&problem=187

太開心啦!!!!這道題從2013年開始困擾我!!今天晚上第四次下定決心把它寫一寫,之前寫了三次(事實上是五個程序)都沒有把它搞定,甚至無從查錯……沒想到今晚居然1A啦太激動了喵哈哈~我先去激動一會

題目大意:給定一個數字n,構建一個從1 ~ n的初始數列,給出 m 個操作,每個操作對應兩個數字 x 和 y 每次將當前序列中的第 x 位到第 y 位翻轉,輸出最終的序列

數據范圍和限制:1<=N<=130000, 1<=M<=2000, 時間限制0.25s, 內存限制 4M(這……)

題目分析:這題貌似是改過數據范圍或者內存限制,反正網上很多大牛直接建了一棵 n 的節點的伸展樹,然后進行區間翻轉,但是現在的數據范圍必然導致MLE。但是這并不意味著伸展樹無計可施我們需要另尋它路。hockey傳授的解法是這樣的:將每個區間視為一個點( 記作[l, r] ),在需要對它的子區間 [i, j] 進行翻轉操作時,我們將它拆成三個點 [l, i]、[i, j]、[j, r],然后在[i, j]上打上翻轉標記……

一般地來講就是這樣:我們的Splay是由若干個區間組成的,當我們需要翻轉區間[i, j]時,先查找出 i - 1 在當前樹中的哪個區間上,然后將它拆成左右兩個區間(約定我們拆分的左區間包含數i - 1)并記錄左區間A,同樣地,我們在樹中查找 j 的位置并拆分,記錄右區間B,將B旋轉到根,再將A旋轉為B的左兒子,則A的右子樹就是待操作的區間,對其進行標記即可。

下面貼出我的代碼,盡可能使注釋詳細

1 //date 20140119 2 #include <cstdio> 3 #include <cstring> 4 5 inline int getint() //讀入優化 6 { 7 int ans (0); char w = getchar(); 8 while('0' > w || '9' < w)w = getchar(); 9 while('0' <= w && w <= '9') 10 { 11 ans = ans * 10 + w - '0'; 12 w = getchar(); 13 } 14 return ans; 15 } 16 17 inline int min(int a, int b){return a < b ? a : b;} 18 inline int max(int a, int b){return a > b ? a : b;} 19 20 int n, m; 21 struct SPlay 22 { 23 struct node 24 { 25 int l, r, rev, revit, size; // l、r為區間左右端點,rev標記以當前節點為根的整棵子樹是否被翻轉,revit標記當前節點所代表的區間是否被翻轉 26 node *s[2], *p; 27 int sum(){return r - l + 1;} 28 int getlr(){return p->s[1] == this;} 29 node(int ll, int rr){l = ll; r = rr; s[0] = s[1] = p = 0; rev = revit = 0; size = sum();} 30 node *link(int w, node *p){s[w] = p; if(p)p->p = this; return this;} 31 void update(){size = (s[0] ? s[0]->size : 0) + (s[1] ? s[1]->size : 0) + sum();} 32 void pushdown()//旋轉標記下放 33 { 34 if(rev) 35 { 36 node *q = s[0]; s[0] = s[1]; s[1] = q; 37 if(s[0])s[0]->rev ^= 1; 38 if(s[1])s[1]->rev ^= 1; 39 revit ^= 1; 40 rev = 0; 41 } 42 } 43 }*root; 44 45 void rot(node *p) 46 { 47 node *q = p->p->p; 48 p->getlr() ? p->link(0, p->p->link(1, p->s[0])) : p->link(1, p->p->link(0, p->s[1])); 49 p->p->update(); 50 if(q)q->link(q->s[1] == p->p, p);else{root = p; p->p = 0;} 51 } 52 53 void splay(node *p, node *tar) 54 { 55 while(p->p != tar && p->p->p != tar) 56 p->getlr() == p->p->getlr() ? (rot(p->p), rot(p)) : (rot(p), rot(p)); 57 if(p->p != tar)rot(p); 58 p->update(); 59 } 60 61 void preset(int l, int r){root = new node(l, r);} 62 //以上是伸展樹的基本操作,如有不熟悉可以參照我博客之前一篇介紹伸展樹的文章 63 int findKth(int k)//尋找當前序列的第k個數所在的區間,并將其旋轉到根,返回值pos是指需要將找到的區間從該區間的第pos個數拆成兩個區間 64 { 65 node *p = root; 66 p->pushdown(); 67 while(!(((p->s[0] ? p->s[0]->size : 0) < k) && ((p->s[0] ? p->s[0]->size : 0) + p->sum() >= k)))//如果沒有找到則繼續找 68 { 69 if((p->s[0] ? p->s[0]->size : 0) >= k){p = p->s[0]; p->pushdown();} 70 else{k -= (p->s[0] ? p->s[0]->size : 0) + p->sum(); p = p->s[1]; p->pushdown();} 71 } 72 k -= (p->s[0] ? p->s[0]->size : 0);//記錄k在該區間中的實際位置,以便拆點 73 splay(p, 0); 74 return k; 75 } 76 77 void divide(node *p, int pos)//將節點p拆成兩個節點,使拆解后的左區間包含恰好pos個數 78 { 79 p->pushdown(); 80 if(p->sum() == pos)return;//如果不需要拆,則不拆 81 node *q1, *q2; 82 if(p->revit) 83 { 84 q1 = new node(p->r - pos + 1, p->r); q1->revit = 1; 85 q2 = new node(p->l, p->r - pos); q2->revit = 1; 86 } 87 else 88 { 89 q1 = new node(p->l, p->l + pos - 1); 90 q2 = new node(p->l + pos, p->r); 91 } 92 q1->link(1, q2->link(1, p->s[1])); 93 q1->link(0, p->s[0]); 94 q2->update(); 95 q1->update(); 96 if(!p->p)root = q1; 97 else p->p->link(p->getlr(), q1); 98 delete p; 99 } 100 101 node *succ()//尋找當前根節點的后繼,屬于基礎操作 102 { 103 root->pushdown(); 104 node *q = root->s[1]; 105 q->pushdown(); 106 while(q->s[0]){q = q->s[0]; q->pushdown();} 107 splay(q, 0); 108 return q; 109 } 110 void deal(int a, int b)//翻轉區間[a,b] 111 { 112 int i = findKth(a - 1);//找到當前區間的前驅 113 divide(root, i); 114 node *p = root; 115 int j = findKth(b);//找到當前區間的后繼 116 divide(root, j); 117 node *q = succ(); 118 splay(p, q); 119 p->s[1]->rev ^= 1;//進行標記 120 p->s[1]->pushdown(); 121 } 122 123 void print(node *p)//以下是一個中根便利進行輸出 124 { 125 p->pushdown(); 126 if(p->s[0])print(p->s[0]); 127 if(p->revit)for(int i = min(p->r, n); i >= max(1, p->l); --i)printf("%d ", i); 128 else for(int i = max(1, p->l); i <= min(p->r, n); ++i)printf("%d ", i); 129 if(p->s[1])print(p->s[1]); 130 } 131 132 void print() 133 { 134 print(root); 135 printf("\n"); 136 } 137 }S; 138 139 int main() 140 { 141 n = getint(); m = getint(); 142 S.preset(0, n + 1);//0和n + 1是哨兵節點,防止越界 143 144 int x, y; 145 for(int i = 1; i <= m; ++i) 146 { 147 x = getint(); y = getint(); 148 S.deal(x + 1, y + 1);//由于0的存在,第x個數實際上是第x + 1個數 149 } 150 S.print(); 151 return 0; 152 }

小注:理解算法之后這道題就是鍛煉編程能力了,希望能給在這道題卡住的同學們一點幫助吧

轉載于:https://www.cnblogs.com/w007878/p/3526297.html

總結

以上是生活随笔為你收集整理的SGU 187 - Twist and whirl -- want to cheat的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲成人基地 | 久久伊人久久 | 国内毛片毛片毛片毛片毛片 | 色哟哟视频在线 | 日本少妇久久 | 国产原创一区 | 日韩黄色av网站 | 好吊妞操 | 亚洲午夜视频 | 日韩成人在线视频观看 | 日韩精品在线播放 | 日韩免费视频一区二区视频在线观看 | 中文字幕综合网 | 色又黄又爽 | 女同性69囗交 | 成人性色生活片 | 国产小毛片 | 国产成人三级在线 | 国产精品3p视频 | 乖疼润滑双性初h | 日本精品在线观看视频 | 色国产视频| 九九综合| 国产成人久久婷婷精品流白浆 | 老熟妇仑乱视频一区二区 | www国产在线| 日本亚洲欧洲色 | 99国产精品久久 | 可乐操亚洲 | 夜夜嗨aⅴ一区二区三区 | 可以免费看的黄色网址 | 精品人妻互换一区二区三区 | av久热| 国产真实乱人偷精品视频 | 亚洲 欧美 激情 小说 另类 | 欧美成片vs欧美 | 亚洲男女在线观看 | 欧美一区在线看 | 在线观看精品国产 | 欧美操操 | 久久免费高清视频 | 少妇高潮露脸国语对白 | 免费草逼视频 | 五月天激情综合网 | 国产美女被草 | 欧美性猛交xxxx乱大交俱乐部 | 好爽又高潮了毛片 | 亚洲天堂一区二区在线 | 精品一区在线观看视频 | 96日本xxxxxⅹxxx17 | 亚洲日本欧美 | 2018国产大陆天天弄 | 狠狠躁狠狠躁视频专区 | 亚洲激情中文 | 97精品人妻麻豆一区二区 | 黄色小说在线观看视频 | 久久国产劲爆∧v内射 | 亚洲AV无码成人国产精品色 | 久久99精品久久久久久噜噜 | 久久一区二 | 亚洲视频欧美视频 | 久久免费影院 | 欧美aa在线| 精品一区二区三区蜜臀 | 日韩av综合网站 | 久久久精品一区二区涩爱 | 日韩网红少妇无码视频香港 | 亚洲日本三级 | 欧美成人一级 | 国产成人精品一区二区三区免费 | 色视频在线播放 | 人体写真 福利视频 | 日本中文字幕在线播放 | 中文在线最新版天堂 | 伊人99re| 青青草亚洲 | 男人与雌性宠物交啪啪 | 日韩精品免费一区 | 我们的2018在线观看免费高清 | 欧美一级免费观看 | 黄a在线 | 五月婷婷丁香激情 | 精品视频一区二区三区 | 激情超碰在线 | 女优色图 | 娇妻第一次尝试交换的后果 | 双性受孕h堵精大肚生子 | 亚洲精品污 | 巨胸喷奶水www久久久免费动漫 | 精品一区二区免费视频 | 国产高清露脸 | 杨幂一区二区三区免费看视频 | 日日操夜夜操狠狠操 | 嫩草午夜少妇在线影视 | 色婷婷狠狠18禁久久 | 日韩欧美国产成人 | 福利片第一页 | 秋霞国产精品 | 美女av免费看 |