icpc的老题了,最近学校oj调出来拿来在训练赛做了,比赛的时候跟队友讨论了两种做法,一种是for循环加树状数组(分析了分析时间复杂度感觉虽然会t,但是应该不存在那种故意卡的数据,就直接交了,没想到一下就过了,于是第二种做法就没有实践),然而没想到比赛刚一结束学长反手就交了这样的一组hack数据卡掉了,QWQ。
//#pragma GCC optimize(4) #include#define rint register int typedef long long ll; using namespace std; const int N=100000+5; int a[N],b[N],c[N],vis[N],n,m; struct node { int x,y,z; }ar[N]; void add(int x,int val) { for(int i=x;i<=n;i+=i&-i)c[i]+=val; } int ask(int x) { int ans=0; for(int i=x;i;i-=i&-i) ans+=c[i]; return ans; } bool cmp(node s,node t) { return s.y<t.y; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) { cin>>a[i]; if(a[i]!=0) { vis[i]=1; add(i,a[i]); } else { add(i,-1); a[i]=-1; } } for(int i=1;i<=m;i++) { cin>>ar[i].x>>ar[i].y>>ar[i].z; } sort(ar+1,ar+1+m,cmp); int flag=0; for(int i=1;i<=m;i++) { int l=ar[i].x,r=ar[i].y; int sum=ask(r)-ask(l-1); for(int j=r;j>=l&&sum if(!vis[j]) { sum+=2; add(j,2); vis[j]=1; a[j]=1; } } if(sum<ar[i].z) { flag=1;break; } } if(flag) printf("Impossible\n"); else { for(int i=1;i) { ) { printf("%d ",a[i]); } printf("%d\n",a[n]); } return 0; } /************************************************************** Problem: 11753 User: Qianwan063 Language: C++ Result: 时间超限 ****************************************************************/
另一种做法是借助了并查集,f[i]指向第一个可以变成1的位置,其他实现原理同上
#pragma GCC optimize(4) #include#define rint register int typedef long long ll; using namespace std; const int N=100000+5; int a[N],b[N],c[N],n,m,f[N]; int getf(int x) { if(f[x]==x) return x; return f[x]=getf(f[x]); // return f[x]==x? x:f[x]=getf(f[x]); } struct node { int x,y,z; }ar[N]; void add(int x,int val) { for(int i=x;i<=n;i+=i&-i)c[i]+=val; } int ask(int x) { int ans=0; for(int i=x;i;i-=i&-i) ans+=c[i]; return ans; } bool cmp(node s,node t) { return s.y<t.y; } int main() { //freopen("in.txt","r",stdin); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=n;i++) { cin>>a[i]; if(a[i]!=0) { int x=getf(i); int y=getf(i-1); f[x]=y; add(i,a[i]); } else { add(i,-1); a[i]=-1; } } for(int i=1;i<=m;i++) { cin>>ar[i].x>>ar[i].y>>ar[i].z; } sort(ar+1,ar+1+m,cmp); int flag=0; for(int i=1;i<=m;i++) { int l=ar[i].x,r=ar[i].y; int sum=ask(r)-ask(l-1); int pos=r; while(sum "%d ",a[i]); } printf("%d\n",a[n]); } return 0; } /************************************************************** Problem: 11753 User: Qianwan063 Language: C++ Result: 正确 Time:53 ms Memory:6628 kb ****************************************************************/=l) { sum+=2; add(pos,2); a[pos]=1; f[pos]=getf(pos-1); } if(sum<ar[i].z) { flag=1;break; } } if(flag) printf("Impossible\n"); else { for(int i=1;i ) { printf(