题意
https://vjudge.net/problem/CodeForces-1253B
把一个序列划成几段,使得每一段都是+x在-x前面,二者均要有。
问划成几段,每一段的大小是多少。
思路
用两个map,p记录能否抵消,q记录每个数是否唯一,sz记录当前段剩余未抵消的个数。
每遇到一个大于0的数x,判断他是否在p和q里,在的话就无解,把它丢到p和q里,sz++。
每遇到一个小于0的数x,检查-x是否在p里,在的话就说明可以抵消,将p[x]置为0,表示已经抵消掉,sz--;否则无解。
当sz==0,表示已经抵消完了,可以成为一段,划分。
代码
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=200005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int a[N]; int main() { // std::ios::sync_with_stdio(false); int n; scanf("%d",&n); map<int,int> p,q;//p用来抵消,q用来控制重复1 int flag=0; for(int i=1; i<=n; i++) { scanf("%d",&a[i]); } int l=0,sz=0; vector<int> v; for(int i=1; i<=n; i++) { if(a[i]>0) { if(p[a[i]]) { puts("-1"); return 0; } if(q[a[i]]) { puts("-1"); return 0; } p[a[i]]=q[a[i]]=1;//,q[a[i]]=1; sz++; } else { a[i]*=(-1); if(!p[a[i]]) { puts("-1"); return 0; } sz--; p[a[i]]=0; } if(sz==0) { q.clear(); v.push_back(i-l); l=i; } } if(sz) { puts("-1"); return 0; } printf("%d\n",v.size()); for(int i:v) { cout<<i<<" "; } cout<<endl; return 0; }