• 分块(区间根号,区间查询


    题目大意就是给你一个区间在区间的各个数都开个根号,然后在让你区间求和

    题目链接https://loj.ac/problem/6281

    主要思路就是如果需更新区间全是0或者全是1就可以不用管。这题我用了set,头尾指针指的值相等且为0或者1就满足条件。

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 typedef long long ll;
      5 const int maxn = 1e5 + 10;
      6 const int inf = 0x3f3f3f3f;
      7 int dir[10][10] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
      8 int color[maxn], l[maxn], r[maxn], pos[maxn], v[maxn], sum[maxn], lz[maxn], t;
      9 set<int> s[1010];
     10 
     11 inline int read() //快读
     12 {
     13     char ch = getchar(); ll k = 0, f = 1;
     14     while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
     15     while(ch >= '0' && ch <= '9') {k = (k << 1) + (k << 3) + ch - '0'; ch = getchar();}
     16     return k * f;
     17 }
     18 
     19 inline void reset(int p)
     20 {
     21     s[p].clear();
     22     s[p].insert(v + l[p], v + r[p] + 1);  //自动从小到大排序
     23     set<int>::iterator it, itt;
     24     it = s[p].begin(); itt = s[p].end(); itt--;   //左闭右开,否则s.end()返回的应该是s.size()
     25     if(sqrt(*it) == 1 && sqrt(*itt) == 1) color[p] = 1;
     26     if(sqrt(*it) == 0 && sqrt(*itt) == 0) color[p] = 1;  
     27 }
     28 
     29 inline void inser(int a, int b)
     30 {
     31     int pa = pos[a], pb = pos[b];
     32     if(pa == pb)
     33     {
     34         for(int i = a; i <= b; ++i)
     35         {
     36             sum[pa] -= v[i];
     37             v[i] = sqrt(v[i]);
     38             sum[pa] += v[i];
     39         }
     40         reset(pa);
     41     }
     42     else
     43     {
     44         for(int i = a; i <= r[pa]; ++i)
     45         {
     46             sum[pa] -= v[i];
     47             v[i] = sqrt(v[i]);
     48             sum[pa] += v[i];
     49         }
     50         reset(pa);
     51 
     52         for(int i = l[pb]; i <= b; ++i)
     53         {
     54             sum[pb] -= v[i];
     55             v[i] = sqrt(v[i]);
     56             sum[pb] += v[i];
     57         }
     58         reset(pb);
     59 
     60         for(int i = pa + 1; i <= pb - 1; ++i)
     61         {
     62             if(color[i]==0)  //如果不是全为1或者0的区间就要进行更新
     63             {
     64                 for(int j = l[i]; j <= r[i]; ++j)
     65                 {
     66                     sum[i] -= v[j];
     67                     v[j] = sqrt(v[j]);
     68                     sum[i] += v[j];
     69                 }
     70                 reset(i);
     71             }
     72         }
     73 
     74     }
     75 }
     76 
     77 inline int findy(int a, int b)
     78 {
     79     int pa = pos[a], pb = pos[b], ans = 0;
     80     if(pa == pb)
     81     {
     82         for(int i = a; i <= b; ++i) ans += v[i];
     83     }
     84     else
     85     {
     86         for(int i = a; i <= r[pa]; ++i) ans += v[i];
     87         for(int i = l[pb]; i <= b; ++i) ans += v[i];
     88         for(int i = pa + 1; i <= pb - 1; ++i)
     89         {
     90             ans += sum[i];
     91         }
     92     }
     93     return ans;
     94 }
     95 
     96 int main()
     97 {
     98     int n, opt, a, b, c;
     99     n = read();
    100     for(int i = 1; i <= n; ++i) v[i] = read();
    101     t = sqrt(n);
    102     for(int i = 1; i <= t; ++i)
    103     {
    104         l[i] = (i-1) * t + 1;
    105         r[i] = i * t;
    106     }
    107 
    108     if(r[t] != n) t++, l[t] = r[t - 1] + 1, r[t] = n;
    109 
    110     for(int i = 1; i <= t; ++i)
    111     {
    112         for(int j = l[i]; j <= r[i]; ++j)
    113         {
    114             pos[j] = i; s[i].insert(j); sum[i] += v[j];  //初始化
    115         }
    116     }
    117 
    118     for(int i = 1; i <= n; ++i)
    119     {
    120         opt = read(); a = read(); b = read(); c = read();
    121         if(opt == 0) inser(a, b);
    122         else cout<<findy(a, b)<<endl;
    123     }
    124 
    125     return 0;
    126 }

    另外需要提下的是RTE和TLE不一定是正常情况,还有可能是用了快读又关了同步流,即getchar()和scanf printf类似,用cin cout再用这些都不能关闭同步流。(直接用scanf printf就没这么多事

    虽然没发生在我身上。。但是一直检查对的代码也是很痛苦的

    也告诉我们学东西要学透彻别老想一知半解

  • 相关阅读:
    python eval()函数
    Linux利用Sysctl命令调整内核参数
    Cookie测试的测试点
    python脚本对 MySQL 数据库进行增删改查
    页面加载经历的过程【转载】
    【转载】shell基础知识
    windows下查看端口占用情况
    Python的hashlib提供了常见的摘要算法
    Python统计文件夹下各个子目录中的文件个数
    Python读取文件下的图片格式
  • 原文地址:https://www.cnblogs.com/a1484755603/p/13411233.html
Copyright © 2020-2023  润新知