题解:CF1896D Ones and Twos
Solution
一眼题,这能蓝?
如果我们能找到一个前缀的和为
否则一定可以找到一个前缀
用树状数组维护区间和可以做到
Code
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int _;
int n,q;
int a[N];
namespace BIT{
int tree[N];
int lowbit(int x){return x&(-x);}
void update(int x,int v){
for(int i=x;i<=n;i+=lowbit(i)) tree[i]+=v;
}
int query(int x){
int ans=0;
for(int i=x;i;i-=lowbit(i)) ans+=tree[i];
return ans;
}
int Q(int l,int r){return query(r)-query(l-1);}
}
using namespace BIT;
int main(){
scanf("%d",&_);
while(_--){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) tree[i]=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),update(i,a[i]);
while(q--){
int op,x,v;
scanf("%d%d",&op,&x);
if(op==1){
int l=1,r=n,p=0;
while(l<=r){
int mid=(l+r)>>1;
if(query(mid)>=x) p=mid,r=mid-1;
else l=mid+1;
}
if(!p){puts("NO");continue;}
if(query(p)==x) puts("YES");
else{
if(query(n-p+1)!=2*(n-p+1)||query(n)-query(p-1)!=2*(n-p+1)) puts("YES");
else puts("NO");
}
}
else{
scanf("%d",&v);
update(x,-a[x]);
a[x]=v;
update(x,a[x]);
}
}
}
return 0;
}