简单线段树。用sort+unique离散化(注意要erase)
#include<cstdio> #include<vector> #include<algorithm> #define con 100100 using namespace std; int op[con],pos[con],sum[con],n; vector<int> in; int tree[270010]; int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b); } void insert(int s,int t,int pos,int v,int id){ if(s==t){ tree[id]=v; return; } int mid=(s+t)>>1; if(mid<pos) insert(mid+1,t,pos,v,id*2+1); else insert(s,mid,pos,v,id*2); tree[id]=gcd(tree[id*2],tree[id*2+1]); } int main() { int i,j,tem; char s[5]; scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%s %d",s,&pos[i]); in.push_back(pos[i]); if(s[0]=='+') op[i]=1; else op[i]=0; } sort(in.begin(),in.end()); in.erase(unique(in.begin(),in.end()),in.end()); int nn=in.size(); for(int i=1;i<=n;i++) pos[i]=lower_bound(in.begin(),in.end(),pos[i])-in.begin(); // 有可能出现in里面为1,2,1,2,2,2,2,2,2(nn=2),这时二分搜2的位置就不是第一个2了,所以要先erase for(i=1;i<=n;i++){ if(op[i]){ sum[pos[i]]++; if(sum[pos[i]]==1){ insert(1,nn,pos[i]+1,in[pos[i]],1); } } else{ sum[pos[i]]--; if(sum[pos[i]]==0){ insert(1,nn,pos[i]+1,0,1); } } if(tree[1]!=0) printf("%d\n",tree[1]); else printf("1\n"); } }