zoj 3765 塊狀鏈表 OR splay

各種操作o(╯□╰)o...不過都挺簡單,不需要lazy標記。

方法1:塊狀鏈表

塊狀鏈表太強大了,區間操作實現起來簡單暴力,效率比splay稍微慢一點,內存開銷小很多。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 const int N = 900;
  7 const int LOW = 260;
  8 const int UP = 320;
  9 int sz[N];
 10 int next[N];
 11 int g[N][2];
 12 int n, m, ps, bl;
 13 
 14 struct B
 15 {
 16     int v, s;
 17 } b[N][N];
 18 
 19 int gcd( int x, int y )
 20 {
 21     if ( y ) return gcd( y, x % y );
 22     return x;
 23 }
 24 
 25 void update( int cur, int stu )
 26 {
 27     g[cur][stu] = 0;
 28     for ( int i = 0; i < sz[cur]; i++ )
 29     {
 30         if ( b[cur][i].s == stu )
 31         {
 32             g[cur][stu] = gcd( g[cur][stu], b[cur][i].v );
 33         }
 34     }
 35 }
 36 
 37 void spilt( int cur )
 38 {
 39     int tmp = next[cur];
 40     int ncur = bl++;
 41     next[cur] = ncur;
 42     next[ncur] = tmp;
 43     for ( int i = sz[cur] / 2; i < sz[cur]; i++ )
 44     {
 45         b[ncur][sz[ncur]++] = b[cur][i];
 46     }
 47     sz[cur] = sz[cur] / 2;
 48     update( cur, 0 );
 49     update( cur, 1 );
 50     update( ncur, 0 );
 51     update( ncur, 1 );
 52 }
 53 
 54 void insert( int pos, int val, int stu )
 55 {
 56     int cur = 0, p = sz[cur];
 57     while ( p < pos + 1 && next[cur] != -1 )
 58     {
 59         cur = next[cur];
 60         p += sz[cur];
 61     }
 62     if ( p < pos + 1 )
 63     {
 64         pos = p;
 65     }
 66     p -= sz[cur];
 67     pos -= p;
 68     for ( int j = sz[cur] - 1; j >= pos; j-- )
 69     {
 70         b[cur][j + 1] = b[cur][j];
 71     }
 72     b[cur][pos].v = val;
 73     b[cur][pos].s = stu;
 74     sz[cur]++;
 75     if ( sz[cur] > UP )
 76     {
 77         spilt(cur);
 78     }
 79     else
 80     {
 81         g[cur][stu] = gcd( g[cur][stu], val );
 82     }
 83 }
 84 
 85 void remove( int pos )
 86 {
 87     int cur = 0, p = sz[cur];
 88     while ( p < pos + 1 && next[cur] != -1 )
 89     {
 90         cur = next[cur];
 91         p += sz[cur];
 92     }   
 93     if ( p < pos + 1 )
 94     {
 95         return ;
 96     }
 97     else
 98     {
 99         p -= sz[cur];
100         pos -= p;
101         int tt = b[cur][pos].s;
102         for ( int j = pos; j < sz[cur] - 1; j++ )
103         {
104             b[cur][j] = b[cur][j + 1];
105         }
106         sz[cur]--;
107         update( cur, tt );
108     }
109 }
110 
111 void reverse( int pos )
112 {
113     int cur = 0, p = sz[cur];
114     while ( p < pos + 1 && next[cur] != -1 )
115     {
116         cur = next[cur];
117         p += sz[cur];
118     }   
119     if ( p < pos + 1 )
120     {
121         return ;
122     }
123     else
124     {
125         p -= sz[cur];
126         pos -= p;
127         int tt = b[cur][pos].s;
128         b[cur][pos].s ^= 1;
129         update( cur, tt );
130         g[cur][tt ^ 1] = gcd( g[cur][tt ^ 1], b[cur][pos].v );
131     }
132 }
133 
134 void modify( int pos, int val )
135 {
136     int cur = 0, p = sz[cur];
137     while ( p < pos + 1 && next[cur] != -1 )
138     {
139         cur = next[cur];
140         p += sz[cur];
141     }   
142     if ( p < pos + 1 )
143     {
144         return ;
145     }
146     else
147     {
148         p -= sz[cur];
149         pos -= p;
150         b[cur][pos].v = val;
151         update( cur, b[cur][pos].s );
152     }
153 }
154 
155 int query( int l, int r, int stu )
156 {
157     int cur = 0, p = sz[cur];
158     while ( p < l + 1 && next[cur] != -1 )
159     {
160         cur = next[cur];
161         p += sz[cur];
162     }        
163     p -= sz[cur];
164     l -= p;  
165     int ncur = 0, q = sz[ncur];
166     while ( q < r + 1 && next[ncur] != -1 )
167     {
168         ncur = next[ncur];
169         q += sz[ncur];
170     }        
171     q -= sz[ncur];
172     r -= q;  
173     int ans = 0;
174     if ( cur != ncur )
175     {
176         for ( int i = next[cur]; i != ncur; i = next[i] )
177         {
178             if ( g[i][stu] == 0 ) continue;
179             ans = gcd( ans, g[i][stu] );
180         }
181         for ( int j = l; j < sz[cur]; j++ )
182         {
183             if ( b[cur][j].s == stu )
184             {
185                 ans = gcd( ans, b[cur][j].v ); 
186             }
187         }
188         for ( int j = 0; j <= r; j++ )
189         {
190             if ( b[ncur][j].s == stu )
191             {
192                 ans = gcd( ans, b[ncur][j].v );
193             }
194         }
195     }
196     else
197     {
198         for ( int j = l; j <= r; j++ )
199         {
200             if ( b[cur][j].s == stu )
201             {
202                 ans = gcd( ans, b[cur][j].v );
203             }
204         }
205     }
206     if ( ans == 0 ) ans = -1;
207     return ans;
208 }
209 
210 int main ()
211 {
212     while ( scanf("%d%d", &n, &m) != EOF )
213     {
214         ps = LOW;
215         memset( sz, 0, sizeof(sz) );
216         memset( next, -1, sizeof(next) );
217         memset( g, 0, sizeof(g) );
218         for ( int i = 0; i < n; i++ )
219         {
220             int la = i / ps, lb = i % ps;
221             scanf("%d%d", &b[la][lb].v, &b[la][lb].s);
222         }
223         int k = 0;
224         while ( ( k + 1 ) * ps < n ) k++;
225         for ( int i = 0; i < k; i++ )
226         {
227             sz[i] = ps;
228             next[i] = i + 1;
229         }
230         sz[k] = n - k * ps;
231         for ( int i = 0; i <= k; i++ )
232         {
233             g[i][0] = g[i][1] = 0;
234             for ( int j = 0; j < sz[i]; j++ )
235             {
236                 int ss = b[i][j].s;
237                 g[i][ss] = gcd( g[i][ss], b[i][j].v );
238             }
239         }
240         bl = k + 1;
241         char op[2];
242         int num1, num2, num3;
243         while ( m-- )
244         {
245             scanf("%s", op);
246             if ( op[0] == 'Q' )
247             {
248                 scanf("%d%d%d", &num1, &num2, &num3);
249                 num1--;
250                 num2--;
251                 printf("%d\n", query( num1, num2, num3 ));
252             }
253             else if ( op[0] == 'I' )
254             {
255                 scanf("%d%d%d", &num1, &num2, &num3);
256                 insert( num1, num2, num3 );
257             }
258             else if ( op[0] == 'D' )
259             {
260                 scanf("%d", &num1);
261                 num1--;
262                 remove(num1);
263             }
264             else if ( op[0] == 'R' )
265             {
266                 scanf("%d", &num1);
267                 num1--;
268                 reverse(num1);      
269             }
270             else if ( op[0] == 'M' )
271             {
272                 scanf("%d%d", &num1, &num2);
273                 num1--;
274                 modify( num1, num2 );
275             }
276         }
277     }
278     return 0;
279 }

方法2:splay

寫起來也不算特別長。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 const int N = 200002;
  7 int v[N];
  8 int s[N];
  9 int n, m;
 10 
 11 int gcd( int x, int y )
 12 {
 13     if ( y ) return gcd( y, x % y );
 14     return x;
 15 }
 16 
 17 struct Node 
 18 {
 19     Node * ch[2];
 20     int g[2];
 21     int val;
 22     int stu;
 23     int rank;
 24     int sz;
 25 
 26     int cmp( int x ) const 
 27     {
 28         if ( x == rank ) return -1;
 29         return x < rank ? 0 : 1;
 30     }
 31 
 32     void maintain()
 33     {
 34         sz = rank = 1;
 35         g[0] = g[1] = 0;
 36         g[stu] = val;
 37         if ( ch[0] != NULL )
 38         {
 39             sz += ch[0]->sz;
 40             rank += ch[0]->sz;
 41             if ( ch[0]->g[0] ) g[0] = gcd( g[0], ch[0]->g[0] );
 42             if ( ch[0]->g[1] ) g[1] = gcd( g[1], ch[0]->g[1] );
 43         }
 44         if ( ch[1] != NULL )
 45         {
 46             sz += ch[1]->sz;
 47             if ( ch[1]->g[0] ) g[0] = gcd( g[0], ch[1]->g[0] );
 48             if ( ch[1]->g[1] ) g[1] = gcd( g[1], ch[1]->g[1] );
 49         }
 50     }
 51 } * root;
 52 
 53 void rotate( Node * & o, int d )
 54 {
 55     Node * k = o->ch[d ^ 1];
 56     o->ch[d ^ 1] = k->ch[d];
 57     k->ch[d] = o;
 58     o->maintain();
 59     k->maintain();
 60     o = k;
 61 }
 62 
 63 void splay( Node * & o, int k )
 64 {
 65     int d = o->cmp(k);
 66     if ( d != -1 )
 67     {
 68         if ( d == 1 ) k -= o->rank;
 69         Node * p = o->ch[d];
 70         int d2 = p->cmp(k);
 71         if ( d2 != -1 )
 72         {
 73             int k2 = ( d2 == 0 ? k : k - p->rank );    
 74             splay( p->ch[d2], k2 );
 75             if ( d == d2 )
 76             {
 77                 rotate( o, d ^ 1 );
 78             }
 79             else
 80             {
 81                 rotate( o->ch[d], d );
 82             }
 83         }
 84         rotate( o, d ^ 1 );
 85     }
 86 }
 87 
 88 Node * build( int l, int r )
 89 {
 90     if ( l > r ) return NULL;
 91     Node * o = new Node();
 92     int mid = ( l + r ) >> 1;
 93     o->sz = r - l + 1;
 94     o->val = v[mid];
 95     o->stu = s[mid];
 96     o->rank = mid - l + 1;
 97     o->g[0] = o->g[1] = 0;
 98     o->g[o->stu] = o->val;
 99     o->ch[0] = build( l, mid - 1 );
100     o->ch[1] = build( mid + 1, r );
101     o->maintain();
102     return o;
103 }
104 
105 int query( int l, int r, int stu )
106 {
107     splay( root, l );
108     splay( root->ch[1], r - l + 2 );
109     return root->ch[1]->ch[0]->g[stu];
110 }
111 
112 void insert( int k, int vv, int ss )
113 {
114     splay( root, k );
115     splay( root->ch[1], 1 );
116     Node * & o = root->ch[1]->ch[0];
117     o = new Node();
118     o->sz = o->rank = 1;
119     o->g[0] = o->g[1] = 0;
120     o->val = vv;
121     o->stu = ss;
122     o->g[ss] = vv;
123     root->ch[1]->maintain();
124     root->maintain();
125 }
126 
127 void remove( int k )
128 {
129     splay( root, k );
130     splay( root->ch[1], 2 );
131     root->ch[1]->ch[0] = NULL;
132     root->ch[1]->maintain();
133     root->maintain();
134 }
135 
136 void reverse( int k )
137 {
138     splay( root, k );
139     root->stu ^= 1;
140     root->maintain();
141 }
142 
143 void modify( int k, int vv )
144 {
145     splay( root, k );
146     root->val = vv;
147     root->maintain();
148 }
149 
150 int main ()
151 {
152     while ( scanf("%d%d", &n, &m) != EOF )
153     {
154         for ( int i = 1; i <= n; i++ )
155         {
156             scanf("%d%d", v + i, s + i);
157         }
158         root = build( 0, n + 1 );
159         char cmd[11];
160         int a, b, c;
161         while ( m-- )
162         {
163             scanf("%s", cmd);
164             if ( cmd[0] == 'Q' )
165             {
166                 scanf("%d%d%d", &a, &b, &c);
167                 int tmp = query( a, b, c );
168                 if ( !tmp ) tmp = -1;
169                 printf("%d\n", tmp);
170             }
171             else if ( cmd[0] == 'I' )
172             {
173                 scanf("%d%d%d", &a, &b, &c);
174                 a++;
175                 insert( a, b, c );
176             }
177             else if ( cmd[0] == 'D' )
178             {
179                 scanf("%d", &a);
180                 remove(a);
181             }
182             else if ( cmd[0] == 'R' )
183             {
184                 scanf("%d", &a);
185                 a++;
186                 reverse(a);
187             }
188             else if ( cmd[0] == 'M' )
189             {
190                 scanf("%d%d", &a, &b);
191                 a++;
192                 modify( a, b );
193             }
194         }
195     }
196     return 0;
197 }

?

轉載于:https://www.cnblogs.com/huoxiayu/p/4736490.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374631.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374631.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374631.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C#公共幫助類】 Image幫助類

大家知道&#xff0c;開發項目除了數據訪問層很重要外&#xff0c;就是Common了&#xff0c;這里就提供了強大且實用的工具。 【C#公共幫助類】 Convert幫助類 Image類&#xff1a; using System; using System.Collections.Generic; using System.Text; using System.IO; usin…

Java泛型快速教程

泛型是Java SE 5.0引入的一種Java功能&#xff0c;在其發布幾年后&#xff0c;我發誓那里的每個Java程序員不僅聽說過它&#xff0c;而且已經使用過它。 關于Java泛型&#xff0c;有很多免費和商業資源&#xff0c;而我使用的最佳資源是&#xff1a; Java教程 Java泛型和集合…

876. 鏈表的中間結點

給定一個頭結點為 head 的非空單鏈表&#xff0c;返回鏈表的中間結點。 如果有兩個中間結點&#xff0c;則返回第二個中間結點 代碼一&#xff1a; 自己想的一個方法 class Solution {public ListNode middleNode(ListNode head) {ListNode p1 head;ListNode p2 head;//i,j…

Hive查詢Join

Select a.val,b.val From a [Left|Right|Full Outer] Join b On (a.keyb.key); 現有兩張表&#xff1a;sales 列出了人名及其所購商品的 ID&#xff1b;things 列出商品的 ID 和名稱&#xff1a; hive> select * from sales; OK Joe 2 Hank 4 Ali 0 Eve 3 Ha…

jquery 獲取easyui combobox選中的值

$(#comboboxlist).combobox(getValue);轉載于:https://www.cnblogs.com/ftm-datablogs/p/5526857.html

調度Java應用程序中的主體

許多項目需要計劃功能&#xff0c;例如我們計劃的工作&#xff0c;重復的工作&#xff0c;異步執行等。 我們的首選方法是使用企業工作調度程序&#xff0c;例如OpenSymphony的Quartz。 使用計劃任務進行編碼時&#xff0c;最棘手的部分之一是執行部分。 這里的主要經驗法則是…

繼承映射關系 joinedsubclass的查詢

會出現下面這樣的錯一般是配置文件中的mapping和映射文件中的package路徑或者class中的name路徑不一致 org.hibernate.MappingException: Unknown entity: com.zh.hibernate.joinedsubclass.Student at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(Sessi…

Spark系列—02 Spark程序牛刀小試

一、執行第一個Spark程序 1、執行程序 我們執行一下Spark自帶的一個例子&#xff0c;利用蒙特卡羅算法求PI&#xff1a; 啟動Spark集群后&#xff0c;可以在集群的任何一臺機器上執行一下命令&#xff1a; /home/spark/spark-1.6.1-bin-hadoop2.6/bin/spark-submit \ --class o…

JVM選項:-client vs -server

您是否曾經在運行Java應用程序時想知道-client或-server開關是什么&#xff1f; 例如&#xff1a; javaw.exe -client com.blogspot.sdoulger.LoopTest也顯示在java.exe的“幫助”中&#xff0c;例如&#xff0c;其中的選項包括&#xff1a; -client選擇“客戶端” VM -serv…

網頁前臺小知識

1.左右布局div塊自適應&#xff0c;首先外邊套一個div,把寬度固定一個px&#xff0c;然后margin設為&#xff10; atuo&#xff1b;這樣他會根據窗口大小自動變換左右距離&#xff0e;就這么簡單&#xff1c;/p> 2.多個標簽共用一個樣式&#xff0c;用&#xff0c;分隔開 p…

統計字符串每個字符出現的次數

//str是個只包含小寫字母的字符串&#xff0c;以下是統計每個字符出現的頻數 int[] cnt new int[26];//toCharArray() for (char ch : str.toCharArray()) {cnt[ch - a]; }//charAt() for(int i 0;i<str.length;i){char ch str.charAt(i);cnt[ch - a]; }

在Java 7中處理文件

以下是The Well-Grounded Java Developer的草稿的修改后的片段。 它使您快速了解與以前版本相比&#xff0c;在Java 7中操作文件要容易得多。 通過使用新的Files類及其許多實用程序方法&#xff0c;您可以僅用一行代碼就可以對文件執行以下操作&#xff1a; 創建 刪除 復制 …

3.1存儲管理操作系統

存儲器管理的對象是主存&#xff08;內存&#xff09;。其主要功能包含分配和回收主存空間、提高主存的利用率、擴充主存、對主存信息實現有效保護。存儲器的結構為&#xff1a;寄存去、緩存、主存、外存。邏輯地址&#xff08;對用戶角度。程序存放的位置&#xff09;、物理地…

學習教材《構建之法》遇到的問題及思路

在學習中每個人都會遇到各種各樣的問題&#xff0c;下面就是我遇到的問題及可能解決問題的思路。 1.如何寫好程序的注釋&#xff0c;每個人都會寫注釋&#xff0c;但是&#xff0c;需要注釋什么&#xff1f; 思路&#xff1a;注釋是為了解釋程序做什么&#xff0c;為什么要這樣…

了解和擴展Java ClassLoader

Java ClassLoader是項目開發中Java的關鍵但很少使用的組件之一。 就我個人而言&#xff0c;我從未在任何項目中擴展ClassLoader&#xff0c;但是擁有自己的可以自定義Java類加載的ClassLoader的想法讓我感到很興奮。 本文將概述Java類加載&#xff0c;然后繼續創建自定義ClassL…

CAD教程-AL對其命令

AL可以實現不規則的對其功能 1.第一步按下AL&#xff0c;按下Enter 2.選擇第一個源點 3.選擇第一個目標點 4.選擇第二個源點 5.選擇第二個目標點 6.按下Enter&#xff0c;完成移位 轉載于:https://www.cnblogs.com/weloveshare/p/4739873.html

使用Spring將POJO公開為JMX MBean

這是一個非常不錯的教程&#xff0c;介紹了如何通過我們最新的JCG合作伙伴 “ The Holy Java ”博客&#xff08;很酷的名字&#xff09;實現“ 用Spring輕松將POJO作為JMX MBean公開 ”。 &#xff08;注意&#xff1a;對原始帖子進行了少量編輯以提高可讀性&#xff09; Jav…

mysql 5.1由于Host為localhost的用戶為空,密碼為空,導致本地用戶無法登陸。

不說了。直接上mysql的用戶數據&#xff0c;第四列里面&#xff0c;host為localhost&#xff0c;用戶為空&#xff0c;密碼為空。 導致在本地登陸的時候除了root的賬戶外&#xff0c;其他賬號不需要密碼即可登陸&#xff0c;并且影響host為 %的用戶登陸。 這里只需要刪除對應的…

scala 88 for替換map,flatmap,filtermap,for,scala,flatmap

王家林親授《DT大數據夢工廠》大數據實戰視頻“Scala深入淺出實戰經典”視頻、音頻和PPT下載&#xff01;第88講&#xff1a;Scala中使用For表達式實現map、flatMap、filter百度云盤&#xff1a;http://pan.baidu.com/s/1mgtgcIG360云盤&#xff1a;http://yunpan.cn/cdXsbctXf…

簡單闡述下OC中UIImage三種創建方式~~~

一. 直接使用imageNamed進行創建 1 UIImage * image [UIImage imageNamed:"1.jpg"]; 簡單說一下這種方式的優缺點&#xff1a; 優點&#xff1a;代碼量少&#xff0c;一行代碼就可以搞定。當程序中多次加載這張圖片時&#xff0c;系統會指向同一塊內存&#xff0c;…