• 【HDU4391】【块状链表】Paint The Wall


    Problem Description
    As a amateur artist, Xenocide loves painting the wall. The wall can be considered as a line consisting of n nodes. Each node has its own color.

    Xenocide spends all day in front of the wall. Sometimes, he paints some consecutive nodes so that these nodes have the same color. When he feels tired, he focuses on a particular color and counts the number of nodes that have this color within a given interval.

    Now Xenocide is tired of counting, so he turns to you for help.
     
    Input
    The input consists of several test cases.
    The first line of each test case contains two integer n, m(1<=n, m<=100000) indicating the length of the wall and the number of queries.
    The following line contains N integers which describe the original color of every position.
    Then m lines follow. Each line contains 4 non-negative integers a, l, r, z(1<=a<=2, 0<=l<=r<n ,0<=z<231).
    a = 1 indicates that Xenocide paints nodes between l and r and the resulting color is z.
    a = 2 indicates that Xenocide wants to know how many nodes between l and r have the color z.
     
    Output
    Print the corresponding answer for each queries.
     
    Sample Input
    5 5 1 2 3 4 0 2 1 3 3 1 1 3 1 2 1 3 3 2 0 3 1 2 3 4 1
     
    Sample Output
    1 0 4 1
     
    Source
    【分析】
    块状链表的裸题,同样可以用线段树做。
    记得在map中把不要用的元素要erase掉,不然很占空间,会超。
    晕了,搞了一个半小时,T了无数遍,后面借鉴了别人的代码....,同样是块状链表,差别怎么这么大(╯‵□′)╯︵┻━┻。
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <vector>
      6 #include <utility>
      7 #include <iomanip>
      8 #include <string>
      9 #include <cmath>
     10 #include <queue>
     11 #include <assert.h>
     12 #include <map>
     13 
     14 const int N = 100000 + 10;
     15 using namespace std;
     16 int n, c, data[N];
     17 int SIZE;
     18 map<int, int>color[334];
     19 
     20 void change2(int l,int r){
     21     int x = l / SIZE;
     22     if(color[x].size() == 1){//整个块只有一个颜色 
     23         map<int, int>::iterator it = color[x].begin();
     24         int last = it->first, cnt = it->second;
     25         if(c == last) return ;//显然等于原来的颜色就没必要修改了 
     26         if(r - l + 1 == cnt){//整个块都修改 
     27             color[x][c] = r - l + 1;
     28             color[x].erase(it);
     29             return;
     30         }
     31         for(int i = SIZE * x; i < n && i < SIZE * ( x + 1 ); i++){
     32             if(i >= l && i <= r) data[i] = c;
     33             else data[i] = last;
     34         }
     35         color[x][c] = r - l + 1;
     36         color[x][last] = cnt - (r - l + 1);
     37     }else 
     38     for(int i = l; i <= r; i++) {//进行直接修改 
     39         if(data[i] == c) continue;
     40         map<int, int>::iterator it = color[x].find(data[i]);
     41         if(it->second == 1) color[x].erase(it);//记住一定要删除不然会超空间 
     42         else it->second--;
     43         color[x][c]++;
     44         data[i] = c;
     45     }
     46 }
     47 //注意这种带2的操作是在同一个块内操作的 
     48 int query2(int l,int r){
     49     int x = l / SIZE;
     50     if(color[x].count(c)){
     51         if(color[x].size() == 1) return r - l + 1;//整块的颜色唯一 
     52         else{
     53             int cnt = 0;
     54             for(int i = l; i <= r; i++) if(data[i] == c) cnt++;
     55             return cnt;
     56         }
     57     } else return 0;
     58 }
     59 
     60 void change(int l,int r){
     61     int x1 = l / SIZE, x2 = r / SIZE;
     62     if(x1 == x2){change2(l, r);return;}
     63     change2(l, SIZE * (x1 + 1) - 1);
     64     change2(SIZE * x2, r);
     65     //真正无奈 
     66     for(int i = x1 + 1; i < x2; i++){
     67         color[i].clear();
     68         color[i][c] = SIZE;
     69     }
     70 }
     71 
     72 int query(int l,int r){
     73     int x1 = l / SIZE, x2 = r / SIZE;
     74     if(x1 == x2) return query2(l,r);
     75     int Ans = query2(l, SIZE * (x1 + 1) - 1) + query2(SIZE * x2 ,r);
     76     for(int i = x1 + 1;i < x2;i++)
     77     if(color[i].count(c)) Ans += color[i][c];
     78     return Ans;
     79 }
     80 
     81 void init(){
     82     SIZE = (int)sqrt(n * 1.0);
     83     for(int i = 0; i < n; i++) scanf("%d", &data[i]);
     84     for(int i = 0; i <= n / SIZE; i++) color[i].clear();
     85     for(int i = 0; i < n; i++) {
     86         int tmp = i / SIZE;
     87         color[tmp][ data[i] ]++;
     88     }
     89 }
     90 
     91 int main(){
     92     #ifdef LOCAL
     93     freopen("data.txt",  "r",  stdin);
     94     freopen("out.txt",  "w",  stdout); 
     95     #endif
     96     int m;
     97     while(scanf("%d%d",&n,&m) != EOF){         
     98         init();                
     99         for (int i = 1; i <= m; i++){
    100             int t, l, r;
    101             scanf("%d%d%d%d", &t, &l, &r, &c);
    102             if(t == 1) change(l,r);
    103             else printf("%d
    ",query(l,r));
    104         }
    105     }
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    (转)Entity Framework 缓存处理与日志监控,(非常重要的技术)
    (转)6步确保 windbg 成功调试 .net
    (转)十天内掌握线性代数:惊人的超速学习实验
    (转)创业需要知道的13句话
    今年阅读书籍计划,C++之STL篇
    不靠广告也盈利:移动应用掘金7大案例剖析(转)
    常用JS操作(复选框、单选框、下拉框)
    Windows系统直接运行jar
    修改打开方式的程序列表中列出程序的名称
    ora12514错误,TNS:监听程序当前无法识别链接描述符中请求的服务
  • 原文地址:https://www.cnblogs.com/hoskey/p/4322726.html
Copyright © 2020-2023  润新知