步行街 | ||||||
| ||||||
Description | ||||||
小A管理着一条大的步行街,步行街上有N家店铺,每家店铺都有很多种商品,小A的工作就是记录每家店铺的商品数。 并且大boss会时常询问小A,从第i家店铺到第j家店铺中有多少家店铺有奇数种商品。但是,每家商品有的时候会进入或下架一些商品,小A来寻求你的帮助了。 | ||||||
Input | ||||||
多组输入数据: 每组数据第一行有两个整数:N :代表步行街上的店铺数(0<N<50000);m:大boss的m个询问(0<m<5000); 第二行有n个数:代表从第一家到最后一家,每一家店铺的商品数num(0<num<50000)。 接下来的m行: C x y代表第x家店铺改变的值y(正数代表上架,负数代表下架,保证数据合理)。 Q i j代表询问第i家店铺到第j家店铺中有多少家店铺有奇数种商品。 | ||||||
Output | ||||||
对于每次大boss的询问:输出结果,每个结果占一行。 | ||||||
Sample Input | ||||||
5 3
1 2 3 4 5
Q 1 5
C 3 1
Q 1 5 |
—————————————————————————————————————————————————————————————————————————————
解题思路:
我们保留原来的商店的信息为num【i】,记录第i家商店的商品数。
我们将a【i】定义为第i家店铺的商品是不是奇数,是的话等于1,不是的话等于0,。
那么sum(i)求出的就是第1家商店到第i家商店一共有几家商店是奇数。这个可以画个x坐标轴理解下。
每次修改值的时候,我们要做的是:看改变前的和改变后的奇偶性发生改变了么,奇偶性没发生变化话的话,我们可以
只修改下num【i】的值;当奇偶性不同的时候:
原来为奇数,之后为偶数,那么我们就让add(i,-1),这样a【i】就从1变成0了。
#include <iostream>#include <string.h>
#include <stdio.h>
#define maxn 50000 +5
using namespace std;
int num[maxn];
int c[maxn];
int n;
int lowbit(int i)
{
return i &- i;
}
void update(int i, int j)
{
while( i <= n)
{
c[i] += j;
i += lowbit(i);
}
}
int sum(int i)
{
int ans = 0;
while( i > 0)
{
ans += c[i];
i -=lowbit(i);
}
return ans;
}
int main(void)
{ int m;
int x,y;
char a;
while(scanf("%d%d",&n, &m) != EOF)
{ memset(c,0,maxn);
for(int i = 1; i<=n; i++)
{
scanf("%d",&num[i]);
if(num[i] % 2 == 1)
update(i, 1);
}
for( int i = 1; i<=m; i++)
{
scanf("%c%d%d",&a, &x, &y);
if(a == 'C')
{
if(num[x] % 2 == 0 )
{
if((num[x] + y)%2 == 1)
update(x,1);
}
if(num[x] % 2 == 1)
{
if((num[x] + y) %2 == 0)
update(x,-1);
}
num[x] += y;
}
if(a == 'Q')
{
cout<<sum(y)-sum(x-1)<<endl;
}
}
}
}