题目描述
我看没人用c语言写题解,就写了一个,怎么说呢这题对c
语言玩家很不友好,应为这题用来判断是查找还是加的
是字符所以我们就要注意一下回车的问题,其实这个问
题不是很坑,题写多了就会注意但最坑的来了,我不知
道我说的对不对如果你们有不同的看法可以发出来一起
讨论。他给的列题不止回车这一个问题,他还有一个问题
就是空格。
嗯??这管空格什么事。
正常给的列题都是(注:|这个只是用来区分的)
10 5|
1 2 3 4 5 6 7 8 9 10|
Q 4 4|
Q 1 10|
Q 2 4|
C 3 6 3|
Q 2 4|
这样只要注意回车就没问题了但他给的列题是这样的
10 5 |
1 2 3 4 5 6 7 8 9 10 |
Q 4 4 |
Q 1 10 |
Q 2 4 |
C 3 6 3 |
Q 2 4 |
嗯???这就很坑了c++还好只要cin就行可我们c语言不行啊
所以我们scanf(” %c”);就要让%c前面空一格空格来吸收这个空格
不然答案可能会少一些数据
我就是这样找了半天问题最后受不了找了我的朋友商量
这是他找出来的感谢他
最后希望这个可以给你带来一些帮助
C 代码
#include<stdio.h>
#define ls(d) d<<1 //左子树
#define rs(d) d<<1|1//右子树
#define N 100010
typedef long long ll;
int n,m,x,y,k;
ll a[N<<2]; //这个要开long long 不然会爆
int lan[N<<2];
void he(int d)
{
a[d]=a[ls(d)]+a[rs(d)]; //左子树加上右子树
}
//创建
void create(int d,int l,int r)
{
int mid=l+r>>1;
lan[d]=0;
if(l==r) {
scanf("%lld",&a[d]);
return ;
}
create(ls(d),l,mid);
create(rs(d),mid+1,r);
he(d);
}
void f(int d,int l,int r,int k)
{
a[d]=a[d]+(r-l+1)*k; //将要加是数值向下压,还是不明白可以上网搜懒标记
lan[d]+=k;
}
void ya(int d,int l,int r) //向下压
{
int mid=l+r>>1;
f(ls(d),l,mid,lan[d]);
f(rs(d),mid+1,r,lan[d]);
lan[d]=0; //应为这个已经给下面的左右子树所以清空
}
void gen(int d,int l,int r,int x,int y,int k)
{
int mid=l+r>>1;
if(x<=l&&r<=y) { //如果l,r在x,y这个区间中我就加上(r-l+1)*k,就代表这个区间都加上了k
a[d]=a[d]+(r-l+1)*k;
lan[d]+=k;
return ;
}
if(lan[d]!=0) //爱写不写,不写也行
ya(d,l,r);
if(x<=mid) gen(ls(d),l,mid,x,y,k);
if(y>mid) gen(rs(d),mid+1,r,x,y,k);
he(d);
}
long long cha(int d,int l,int r,int x,int y)
{
int mid=l+r>>1;
long long res=0;
if(x<=l&&r<=y) return a[d]; //如果l,r在x,y这个区间中我就返回l,r这个区间的长度
if(lan[d]!=0)//可加可不加
ya(d,l,r);
if(x<=mid) res+=cha(ls(d),l,mid,x,y);
if(y>mid) res+=cha(rs(d),mid+1,r,x,y);
return res;
}
int main()
{
scanf("%d%d",&n,&m);
create(1,1,n);
while(m--)
{
getchar();//吸收回车
char t;
scanf(" %c%d%d",&t,&x,&y);//这个%c前面的空格一定要加上不然就会出现一些数据最后一个没了的情况
// 这个也可以写成scanf(" \n%c%d%d",&t,&x,&y);我朋友想的
// scanf(" \n%c%d%d",&t,&x,&y);
if(t == 'Q') {
printf("%lld\n",cha(1,1,n,x,y));
} else {
scanf("%d",&k);
gen(1,1,n,x,y,k);
}
}
return 0;
}
//可ac