• A Simple Problem with Integers POJ


    题目链接:https://cn.vjudge.net/problem/POJ-3468

    题目大意:区间加减+区间查询操作。

    具体思路:本来是一个线段树裸题,为了学习分块就按照分块的方法做吧。

    分块真的好暴力,,,(但是还是挺优美的)。

    说一下各个数组的作用。

    a数组,代表每一个点的值。

    sum数组,代表分块后每一段的值。

    add数组,相当于线段树中的lazy标记,记录的数当前这一整段添加的值。

    l数组,r数组,记录每一段的左端点和右端点。

    belong数组,记录每一个数属于哪一个分块中。

    AC代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<string>
     4 #include<stdio.h>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<math.h>
     8 using namespace std;
     9 # define ll long long
    10 const int maxn = 1e6+100;
    11 ll a[maxn],sum[maxn],add[maxn];
    12 int l[maxn],r[maxn];
    13 int belong[maxn];
    14 void buildblock(int t){
    15 int tmp=(int)sqrt(t*1.0);
    16 int tot=t/tmp;
    17 if(t%tmp)tot++;
    18 for(int i=1;i<=t;i++){
    19 belong[i]=(i-1)/tmp+1;
    20 }
    21 for(int i=1;i<=tot;i++){
    22 l[i]=(i-1)*tmp+1;
    23 r[i]=i*tmp;
    24 }
    25 r[tot]=t;
    26 for(int i=1;i<=tot;i++){
    27 for(int j=l[i];j<=r[i];j++){
    28 sum[i]+=a[j];
    29 }
    30 }
    31 }
    32 void update(int st,int ed,ll val){
    33 if(belong[st]==belong[ed]){
    34 for(int i=st;i<=ed;i++){
    35 a[i]+=val;
    36 sum[belong[st]]+=val;
    37 }
    38 return ;
    39 }
    40 for(int i=st;i<=r[belong[st]];i++){
    41 a[i]+=val;
    42 sum[belong[st]]+=val;
    43 }
    44 for(int i=l[belong[ed]];i<=ed;i++){
    45 a[i]+=val;
    46 sum[belong[ed]]+=val;
    47 }
    48 for(int i=belong[st]+1;i<belong[ed];i++){
    49 add[i]+=val;
    50 }
    51 }
    52 ll ask(int st,int ed){
    53 ll ans=0;
    54 if(belong[st]==belong[ed]){
    55 for(int i=st;i<=ed;i++){
    56 ans+=a[i]+add[belong[st]];
    57 }
    58 return ans;
    59 }
    60 for(int i=st;i<=r[belong[st]];i++){
    61 ans+=a[i]+add[belong[st]];
    62 }
    63 for(int i=l[belong[ed]];i<=ed;i++){
    64 ans+=a[i]+add[belong[ed]];
    65 }
    66 for(int i=belong[st]+1;i<belong[ed];i++){
    67 ans+=sum[i]+add[i]*(r[i]-l[i]+1);
    68 }
    69 return ans;
    70 }
    71 int main(){
    72 //freopen("hqx.in","r",stdin);
    73 int n,m;
    74 scanf("%d %d",&n,&m);
    75 for(int i=1;i<=n;i++){
    76 scanf("%lld",&a[i]);
    77 }
    78 buildblock(n);
    79 char str[10];
    80 int st,ed;
    81 ll cost;
    82 while(m--){
    83 scanf("%s",str);
    84 if(str[0]=='Q'){
    85 scanf("%d %d",&st,&ed);
    86 printf("%lld
    ",ask(st,ed));
    87 }
    88 else if(str[0]=='C'){
    89 scanf("%d %d %lld",&st,&ed,&cost);
    90 update(st,ed,cost);
    91 }
    92 }
    93 return 0;
    94 }
  • 相关阅读:
    蓝桥杯入门训练
    <泛> STL
    传递 hdu 5961 拓扑排序有无环~
    Alice and Bob hdu 4268
    Bipartite Graph hdu 5313 bitset 并查集 二分图
    Bomb HDU 3555 dp状态转移
    不要62 hdu 2089 dfs记忆化搜索
    Leaving Auction CF 749D
    Moo University
    算法(三)
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10458544.html
Copyright © 2020-2023  润新知