hdu4339--Query(二分+树状数组)

题目大意:

给定两个字符串,有两种操作

1: 把第a(a==1 || a==2)个串第i个位置得字符改为c(输入的字符)

2:   求从第i个字符起接下来连续相同字符的个数

解题方法:

对于两个字符串,对应第i个位置得字符相同标1,不同标0,分别加入数组数组中

查询的话从第i个位置起到两个串最大长度的位置,通过二分查询结果。如果连续相同的话,区间和将等于区间的长度。

树状数组代码:

View Code
  1 //Accepted    4339    3218MS    10008K    1651 B    G++
  2 #include <stdio.h>
  3 #include <string.h>
  4 #define MAX 1000001
  5 
  6 char s1[MAX],s2[MAX];
  7 int c[MAX],tt[MAX];
  8 inline int lowbit(int a) { return a & (-a); }
  9 inline int maxx(int a,int b) { return a > b ? a : b; }
 10 void insert(int x,int d)
 11 {
 12     while(x < MAX)
 13     {
 14         c[x] += d;
 15         x += lowbit(x);
 16     }
 17 }
 18 
 19 int getsum(int x)
 20 {
 21     int sum = 0;
 22     while(x > 0)
 23     {
 24         sum += c[x];
 25         x -= lowbit(x);
 26     }
 27     return sum;
 28 }
 29 
 30 void query(int l,int r)
 31 {
 32     int num = l - 1;
 33     while(l <= r)
 34     {    
 35         int mid = (l + r) >> 1;
 36         int k = getsum(mid) - getsum(num);
 37         if(k == mid - num)
 38             l = mid + 1;
 39         else
 40             r = mid - 1;
 41     }
 42     printf("%d\n",r-num);
 43 }
 44 
 45 int main(void)
 46 {
 47     int i,j,t;
 48     scanf("%d",&t);
 49     for(i = 1; i <= t ; i++)
 50     {
 51         memset(c,0,sizeof(c));
 52         memset(tt,0,sizeof(tt));
 53         scanf("%s",s1);
 54         scanf("%s",s2);
 55         int len1,len2,len;
 56         len1 = strlen(s1);
 57         len2 = strlen(s2);
 58         len = maxx(len1,len2);
 59         for(j=0;j<len;j++)
 60         {
 61             if(s1[j]==s2[j])
 62             {
 63                 tt[j+1] = 1;
 64                 insert(j+1,1);
 65             }
 66         }
 67         int q;
 68         printf("Case %d:\n",i);
 69         scanf("%d",&q);
 70         while(q--)
 71         {
 72             int id,a;
 73             scanf("%d",&id);
 74             if(id == 1)
 75             {
 76                 int x;
 77                 char ch;
 78                 scanf("%d %d %c",&a,&x,&ch);
 79                 if(a == 1)
 80                 {
 81                     s1[x] = ch;
 82                 }
 83                 else
 84                 {
 85                     s2[x] = ch;
 86                 }
 87                 if(s1[x] == s2[x])
 88                 {
 89                     if(tt[x+1] == 0)
 90                     {
 91                         insert(x+1,1);
 92                         tt[x+1] = 1;
 93                     }
 94                 }
 95                 else
 96                 {
 97                     if(tt[x+1] == 1)
 98                     {
 99                         insert(x+1,-1);
100                         tt[x+1] = 0;
101                     }
102                 }
103             }
104             else
105             {
106                 scanf("%d",&a);
107                 query(a+1,len);
108             }
109         }
110     }
111     return 0;
112 }

同样的方法用线段树求和就超时了,树状数组求和的效率还是比较高的

线段树代码:

View Code
  1 //tle
  2 #include <cstdio>
  3 #include <cstring>
  4 
  5 #define lson l , m , rt << 1
  6 #define rson m + 1 , r , rt << 1 | 1
  7 #define maxn 1000005
  8 int sum[maxn<<2];
  9 char s1[maxn],s2[maxn];
 10 int tt[maxn];
 11 inline int maxx(int a,int b) { return a > b ? a : b; }
 12 void PushUP(int rt) {
 13     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
 14 }
 15 void build(int l,int r,int rt) {
 16     if (l == r) {
 17         sum[rt] = tt[l];
 18         return ;
 19     }
 20     int m = (l + r) >> 1;
 21     build(lson);
 22     build(rson);
 23     PushUP(rt);
 24 }
 25 void update(int p,int add,int l,int r,int rt) {
 26     if (l == r) 
 27     {
 28         sum[rt] += add;
 29         return ;
 30     }
 31     int m = (l + r) >> 1;
 32     if (p <= m) update(p , add , lson);
 33     else update(p , add , rson);
 34     PushUP(rt);
 35 }
 36 int getsum(int L,int R,int l,int r,int rt) {
 37     if (L <= l && r <= R) {
 38         return sum[rt];
 39     }
 40     int m = (l + r) >> 1;
 41     int ret = 0;
 42     if (L <= m) ret += getsum(L , R , lson);
 43     if (R > m) ret += getsum(L , R , rson);
 44     return ret;
 45 }
 46 void query(int l,int r)
 47 {
 48     int num = l - 1;
 49     int len = r;
 50     while(l <= r)
 51     {    
 52         int mid = (l + r) >> 1;
 53         int k = getsum(num+1,mid,1,len,1);
 54         if(k == mid - num)
 55             l = mid + 1;
 56         else
 57             r = mid - 1;
 58     }
 59     printf("%d\n",r-num);
 60 }
 61 
 62 int main(void)
 63 {
 64     int i,j,t;
 65     scanf("%d",&t);
 66     for(i = 1; i <= t ; i++)
 67     {
 68         memset(sum,0,sizeof(sum));
 69         memset(tt,0,sizeof(tt));
 70         scanf("%s",s1);
 71         scanf("%s",s2);
 72         int len1,len2,len;
 73         len1 = strlen(s1);
 74         len2 = strlen(s2);
 75         len = maxx(len1,len2);
 76         for(j=0;j<len;j++)
 77         {
 78             if(s1[j]==s2[j])
 79             {
 80                 tt[j+1] = 1;
 81                 update(j+1,1,1,len,1);
 82             }
 83         }
 84         int q;
 85         printf("Case %d:\n",i);
 86         scanf("%d",&q);
 87         while(q--)
 88         {
 89             int id,a;
 90             scanf("%d",&id);
 91             if(id == 1)
 92             {
 93                 int x;
 94                 char ch;
 95                 scanf("%d %d %c",&a,&x,&ch);
 96                 if(a == 1)
 97                 {
 98                     s1[x] = ch;
 99                 }
100                 else
101                 {
102                     s2[x] = ch;
103                 }
104                 if(s1[x] == s2[x])
105                 {
106                     if(tt[x+1] == 0)
107                     {
108                         update(x+1,1,1,len,1);
109                         tt[x+1] = 1;
110                     }
111                 }
112                 else
113                 {
114                     if(tt[x+1] == 1)
115                     {
116                         update(x+1,-1,1,len,1);
117                         tt[x+1] = 0;
118                     }
119                 }
120             }
121             else
122             {
123                 scanf("%d",&a);
124                 query(a+1,len);
125             }
126         }
127     }
128     return 0;
129 }
posted @ 2012-09-25 19:17  Wheat″  阅读(147)  评论(0编辑  收藏  举报