• hdu 4288 (成都赛区2012网络赛)


     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 #define mid (l+r)>>1
    10 #define ls rt<<1
    11 #define rs rt<<1|1
    12 #define lson l,m,rt<<1
    13 #define rson m+1,r,rt<<1|1
    14 
    15 #define MAXN 100010
    16 int sum[MAXN<<2]; //区间的元素个数
    17 __int64 ans[MAXN<<2][5];//分别表示mod5
    18 int key[MAXN];//离散化用
    19 int x[MAXN];
    20 
    21 char op[MAXN][10];
    22 
    23 void pushup(int rt)
    24 {
    25     for(int i=0;i<5;i++)
    26     {
    27         ans[rt][i]=ans[ls][i]+ans[rs][(i-sum[ls]%5+5)%5];
    28     }
    29 }
    30 
    31 void build(int l,int r,int rt)
    32 {
    33     sum[rt]=0;
    34     memset(ans[rt],0,sizeof(ans[rt]));
    35     if(l==r)   
    36         return;
    37     int m = mid;
    38     build(lson);  
    39     build(rson);
    40 }
    41 
    42 int flag;//判断用
    43 void update(int p,int l,int r,int rt)
    44 {
    45     sum[rt]+=2*flag-1;
    46     if (l==r)    
    47     {
    48         ans[rt][1]=flag*key[p];//叶子节点的值mod5肯定为1
    49         return ;
    50     }
    51     int m=mid;
    52     if (p<= m)       
    53         update(p,lson);
    54     else    
    55         update(p,rson);
    56     pushup(rt);     
    57 }
    58 
    59 int main()
    60 {
    61     int n,tot=0;
    62     while(scanf("%d",&n) != EOF)
    63     {
    64         tot=0;
    65         for(int i=0;i<n;i++)
    66         {    
    67             scanf("%s",op[i]);
    68             if(op[i][0]=='a' || op[i][0]=='d')
    69             {    
    70                 scanf("%d",&x[i]);
    71                 key[tot++]=x[i];
    72             }
    73         }
    74         sort(key,key+tot);
    75         tot = unique(key,key+tot) - key;
    76         build(1,tot,1);
    77         for(int i=0;i<n;i++)
    78         {
    79             int pos = lower_bound(key,key+tot,x[i]) - key;
    80             if(op[i][0] == 's')
    81                 printf("%I64d\n",ans[1][3]);
    82             else
    83             {
    84                 if(op[i][0]=='a')
    85                     flag=1;
    86                 else
    87                     flag=0;
    88                 update(pos,1,tot,1);
    89             }
    90         }
    91     }
    92     return 0;
    93 }

    线段树   + 离散化 :

    这题是codeforce上的原题。。。o(︶︿︶)o 唉。

    用ans[][5]分别表示区间内mod5==i的五种情况的和。比如ans[][2]==4,表示这个区间内下表mod5==2的值的和为4.

    假如我们 求  i ==  3 时 (表示  %5 == 3)

    对于左子树我们直接求就可以 ,但是对于右子树,我们要知道 在 i== 3 的 情况下 ,右子树的元素的下标应该是 %5 == 几?

    ans[rt][i]=ans[ls][i]+ans[rs][(i-sum[ls]%5+5)%5];

     

  • 相关阅读:
    数据库被黑后留下的数据
    cron(CronTrigger)表达式用法
    nodeJS常用的定时执行任务的插件
    css实现隐藏滚动条
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
  • 原文地址:https://www.cnblogs.com/Missa/p/2697666.html
Copyright © 2020-2023  润新知