zoukankan      html  css  js  c++  java
  • 【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
  • 相关阅读:
    php 转化整型需要注意的地方
    生成6位随机数
    php://input
    ios常见问题 经验之谈
    ios 从前台返回到回台 从后台返回到前台 或者 支付宝支付订单后 对界面进行操作
    ios根据文本自适应 然后 搭建类似如下效果
    iosTableView 局部全部刷新以及删除编辑操作
    ios打开系统自带APP
    iOS通过URL Scheme启动app(收集了常用的app的URL Scheme)
    ios UIApplocation 中APP启动方式
  • 原文地址:https://www.cnblogs.com/hoskey/p/4322726.html
Copyright © 2011-2022 走看看