zoukankan      html  css  js  c++  java
  • 【BZOJ3211】【并查集+树状数组】花神游历各国

    Description

     

    Input

     

    Output

    每次x=1时,每行一个整数,表示这次旅行的开心度

    Sample Input

    4

    1 100 5 5

    5

    1 1 2

    2 1 2

    1 1 2

    2 2 3

    1 1 4

    Sample Output

    101

    11

    11
    【分析】
    开始看一眼觉得线段树可做。
    后来看题解用树状数组瞬秒......orzzz,注意到任何一个int都可以在很小的次数下变为1,所以直接暴力单点修改,将变成1的数parent设为它右边的数。
    注意,输入中可能会有很多的0....直接写优化不好会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 <map>
    12 
    13 const int MAXN = 100000 + 10; 
    14 const int MAX = 30000 + 10; 
    15 using namespace std;
    16 typedef long long ll;
    17 int n;
    18 ll C[MAXN];
    19 int data[MAXN], parent[MAXN];
    20 
    21 int SQRT(int x){return (int)floor(sqrt((double)x * 1.0));}
    22 int lowbit(int x){return x & -x;}
    23 void add(int x, int val){
    24      while (x <= n){
    25            C[x] += val;
    26            x += lowbit(x);
    27      }
    28      return;
    29 }
    30 ll sum(int x){
    31     ll cnt = 0;
    32     while (x > 0){
    33           cnt += C[x];
    34           x -= lowbit(x); 
    35     }
    36     return cnt;
    37 }
    38 int find(int x) {return parent[x] == x? x : parent[x] = find(parent[x]);}
    39 void init(){
    40      memset(C, 0, sizeof(C));
    41      scanf("%d", &n);
    42      for (int i = 1; i <= n; i++){
    43          scanf("%d", &data[i]);
    44          add(i, data[i]);
    45          parent[i] = i;
    46          if (data[i] == 1 || data[i] == 0) parent[i] = i + 1;
    47      }
    48      parent[n + 1] = n + 1;
    49 }
    50 void work(){
    51      int q;
    52      scanf("%d", &q);
    53      for (int i = 1; i <= q; i++){
    54          int t, x, y;
    55          scanf("%d%d%d", &t, &x, &y);
    56          if (t == 1) printf("%lld
    ", sum(y) - sum(x - 1));
    57          else{
    58               for (int i = x; i <= y; i = find(i + 1)){
    59                   int tmp = data[i];
    60                   data[i] = SQRT(data[i]);
    61                   add(i, data[i] - tmp);
    62                   if (data[i] <= 1) parent[i] = find(i + 1);
    63               }
    64          }
    65      } 
    66 }
    67  
    68 int main(){
    69     int T;
    70     #ifdef LOCAL
    71     freopen("data.txt",  "r",  stdin);
    72     freopen("out.txt",  "w",  stdout); 
    73     #endif
    74     init();
    75     work();
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    mysql dns反说明的成绩
    Solaris 11 安装图解(1)
    Meld 1.1.5
    Open Movie Editor-视频编纂器
    Solaris 11 装配图解(6)
    Pidgin 2.0.2
    Subversion 1.4.4 发布
    Solaris 11 安装图解(5)
    Solaris 11 安置图解(3)
    HTML 实体盘诘东西
  • 原文地址:https://www.cnblogs.com/hoskey/p/4322137.html
Copyright © 2011-2022 走看看