poj 2777線段樹應用

來源:互聯網
上載者:User

標籤:

敲了n遍....RE愉快的debug了一晚上...發現把#define maxn = 100000 + 10 改成 #define maxn = 100010 就過了....感受一下我呵呵噠的表情....

貌似這個題用了很經典的線段樹和位元運算。懂了。但不是很懂。確實覺得用的很巧妙。只想說。好坑。

  1 #include<iostream>  2 #include<cstdio>  3 #include<cstring>  4 using namespace std;  5 #define N = 100010  6   7 struct Tree{  8     int l,r;  9     int col;    //  用一個32位的int型,每一位對應一種顏色,用位元運算代替bool col[32] 10     bool cover; //  表示這個區間都被塗上同一種顏色,線段樹效率的體現,否則插入就是0(n)了。 11 }tree[N<<2]; 12  13 void PushUp(int rt){    // 最後遞迴回來再更改父節點的顏色 14     tree[rt].col=tree[L(rt)].col | tree[R(rt)].col; 15 } 16  17 void build(int l, int r, int root) { 18     tree[root].l = l; 19     tree[root].r = r; 20     tree[root].col = 1; 21     tree[root].cover = 1; 22  23     if (l == r) return; 24     int mid = (l+r)/2; 25     build(l, mid, 2*root); 26     build(mid+1, r, 2*root+1); 27 } 28  29  30 void PushDown(int root) { // 把標記向下傳遞 31     tree[2*root].col = tree[root].col; 32     tree[2*root].cover = 1; 33     tree[2*root+1].col = tree[root].col; 34     tree[2*root+1].cover = 1; 35     tree[root].cover = 0;  // 懂了。 36 } 37 void update(int val, int l, int r, int root) { // 更新某個區間的顏色 38     if (l <= tree[root].l && tree[root].r <= r) { 39        tree[root].col = val; // 說明這個區間只包含一種顏色了。而且是val. 所以修改完成、get it!!! 40        tree[root].cover = 1; 41        return ; 42     } 43  44     if (tree[root].col == val) return; // 說明當前的區間內的顏色已經只有這一種了。所以沒必要再往下、??剪枝 45     if (tree[root].cover) PushDown(root);  // 因為下面可能要修改這個區間的某個子區間的顏色了。 46     // 否則就不斷的向下分解區間 47     int mid = (tree[root].l+tree[root].r)/2; 48     if (r <= mid) update(val, l, r, 2*root); 49     else if (l >= mid+1) update(val, l, r, 2*root+1); 50     else { 51        update(val, l, mid, 2*root); 52        update(val, mid+1, r, 2*root+1); 53     } 54     PushUp(root);  // 遞迴修改完孩子節點的顏色後 修改父親節點的顏色 55 } 56  57 int sum; 58  59 void query(int L,int R,int rt){ 60     if(L<=tree[rt].l && R>=tree[rt].r){ 61         sum |= tree[rt].col; 62         return ; 63     } 64     if(tree[rt].cover){     //  這個區間全部為1種顏色,就沒有繼續分割區間的必要了 65         sum |= tree[rt].col;     //  顏色種類相加的位元運算代碼 66         return; 67     } 68     int mid=(tree[rt].l+tree[rt].r)>>1; 69     if(R<=mid) 70         query(L,R,L(rt)); 71     else if(L>=mid+1) 72         query(L,R,R(rt)); 73     else{ 74         query(L,mid,L(rt)); 75         query(mid+1,R,R(rt)); 76     } 77 } 78  79 int solve(){ 80     int ans=0; 81     while(sum){ 82         if(sum&1) 83             ans++; 84         sum>>=1; 85     } 86     return ans; 87 } 88  89 void swap(int &a, int &b) { 90     int t = a; 91     a = b; 92     b = t; 93 } 94  95 int main() { 96     int l, n, m; 97     while(~scanf("%d%d%d", &l, &n, &m)) { 98         build(1, l, 1); 99         char op[10];100         int a, b, c;101 102         for (int i=0; i<m; ++i) {103             scanf("%s", op);104             if (op[0] == ‘C‘) {105               scanf("%d%d%d", &a, &b, &c);106               if (a > b) swap(a, b);107               update(1<<(c-1), a, b, 1);108             }109             else if (op[0] == ‘P‘) {110                scanf("%d%d", &a, &b);111                if (a > b) swap(a, b);112                sum = 0;113                query(a, b, 1);114                printf("%d\n",solve());115             }116         }117     }118     return 0;119 }
View Code

 

poj 2777線段樹應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.