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];

 

你可能感兴趣的:(2012)