6139:Interval Product
問題文
https://icpcarchive.ecs.baylor.edu/external/61/6139.pdf
数列とクエリが与えられる。クエリは以下の2種類である。
C a b 数列のa番目をbに更新する。
P a b 数列の区間[a,b]の積が負であれば-、0であれば0、正であれば+を出力する。
セグメント木を実装した。各ノードには
その区間の積が負ならば-1、0ならば0、正ならば1
という情報を持たせた。
#include<iostream> #include<vector> #include<algorithm> using namespace std; const int max_n=1<<17; int n,dat[max_n*2]; void init(int n_){ n=1; while(n<n_)n*=2; for(int i=0;i<2*n;i++)dat[i]=0; } void update(int k,int a){ k+=n-1; if(a>0)dat[k]=1; if(a==0)dat[k]=0; if(a<0)dat[k]=-1; while(k>0){ k=(k-1)/2; dat[k]=dat[k*2+1]*dat[k*2+2]; } } int query(int a,int b,int k,int l,int r){ if(r<=a || b<=l)return 1; if(a<=l && r<=b)return dat[k]; else{ int vl=query(a,b,k*2+1,l,(l+r)/2); int vr=query(a,b,k*2+2,(l+r)/2,r); return vl*vr; } } int main(void){ int N,K; while(cin >> N >> K){ init(N); for(int i=0;i<N;i++){ int in; cin >> in; update(i,in); } for(int i=0;i<K;i++){ char ch; int a,b; cin >> ch >> a >> b; if(ch=='C')update(a-1,b); else if(ch=='P'){ int res=query(a-1,b,0,0,n); if(res==0)cout << 0; else if(res>0)cout << '+'; else if(res<0)cout << '-'; } } cout << endl; } return 0; }