• nyoj123 士兵杀敌(四)


     1 #include<stdio.h>
     2 #define N 1000010
     3 struct node{
     4     int l,r;
     5     int inc;
     6 }tree[3*N];
     7 inline void build(int l,int r,int i)
     8 {
     9     tree[i].l=l;
    10     tree[i].r=r;
    11     if(l<r){
    12         int mid=(l+r)>>1;
    13         build(l,mid,i<<1);
    14         build(mid+1,r,(i<<1)+1);
    15     }
    16 }
    17 inline void add(int l,int r,int inc,int i)
    18 {
    19     if(l==tree[i].l&&tree[i].r==r){//要是l为0的话就不能这样写了,否则RE,死循环 
    20         tree[i].inc+=inc;//加的时候单单加到本段,不往下压 
    21         return;
    22     }
    23     int mid=(tree[i].l+tree[i].r)>>1;
    24     if(r<=mid) add(l,r,inc,i<<1);
    25     else if(l>mid) add(l,r,inc,(i<<1)+1);
    26     else{
    27         add(l,mid,inc,i<<1);
    28         add(mid+1,r,inc,(i<<1)+1);
    29     }
    30 }
    31 inline int query(int k,int i)
    32 {
    33     if(tree[i].l<tree[i].r){//查询的时候父辈的inc值往下压,直到压到叶子节点为止 
    34         if(tree[i].inc){
    35             tree[i<<1].inc+=tree[i].inc;
    36             tree[(i<<1)+1].inc+=tree[i].inc;
    37             tree[i].inc=0;//记得清零 
    38         }
    39         int mid=(tree[i].l+tree[i].r)>>1;
    40         if(k<=mid) return query(k,i<<1);
    41         else return query(k,(i<<1)+1);
    42     }
    43     return tree[i].inc;//返回此叶子节点的值,也即是结果 
    44 }
    45 int main()
    46 {
    47     int a,b,inc,n,q;
    48     char cmd[6];
    49     scanf("%d%d",&q,&n);
    50     build(1,n,1);
    51     while(q--){
    52         scanf("%s",cmd);
    53         if(*cmd=='A'){
    54             scanf("%d%d%d",&a,&b,&inc);
    55             if(!a) a++;//真像讨论区有人说的那样本题测试数据有Bug,a可能为0,坑爹啊! 
    56             add(a,b,inc,1);
    57         }else{
    58             scanf("%d",&a);
    59             printf("%d\n",query(a,1));
    60         }
    61     }
    62     return 0;
    63 }
    64 //本题貌似用树状数组做更加简洁,以后说吧!!先把线段树搞定!!


    贴下最优代码:
     1 #include<cstdio>
     2 #include<cstring>
     3 const int M=1000010;
     4 int data[M];
     5 int Max;
     6 inline int LowBit(int n)
     7 {
     8     return n&(-n);
     9 }
    10 void Plus(int n,int value) //前n项每项增加value
    11 {
    12     while(n>0)
    13     {
    14         data[n]+=value;
    15         n-=LowBit(n);
    16     }
    17 }
    18 int Get(int n) //获取每个位置的值
    19 {
    20     int sum=0;
    21     while(n<=Max)
    22     {
    23         sum+=data[n];
    24         n+=LowBit(n);
    25     }
    26     return sum;
    27 }
    28 char cmd[50];
    29 int main()
    30 {
    31     int n,a,b,v;
    32     scanf("%d%d",&n,&Max);
    33     while(n--)
    34     {
    35         scanf("%s",cmd);
    36         if(!strcmp(cmd,"ADD"))
    37         {
    38             scanf("%d%d%d",&a,&b,&v);
    39             Plus(a-1,-v);
    40             Plus(b,v);
    41         }
    42         else
    43         {
    44             scanf("%d",&a);
    45             printf("%d\n",Get(a));
    46         }
    47     }
    48     
    49 
    50 }
    
    
  • 相关阅读:
    CCPC2018-湖南全国邀请赛
    2019中山大学程序设计竞赛
    [POJ]poj1185 炮兵营地(状压DP)
    [CF]Codeforces Round #551 (Div. 2)
    [EOJ]2019 ECNU XCPC April Selection #1
    [现场赛]“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛
    欧拉函数 欧拉筛法 欧拉定理
    [CF]301D Yaroslav and Divisors
    岸芷汀兰的诗集(持续更新)
    模板柱(持续更新)
  • 原文地址:https://www.cnblogs.com/shihuajie/p/2635785.html
Copyright © 2020-2023  润新知