#include <stdio.h> #include <string.h> #define maxn 100001 struct node{ int l,r,w; }e[maxn*4]; void build(int a,int b,int c) { e[c].l=a; e[c].r=b; e[c].w=0; if(a==b) return; int mid=(a+b)/2; build(a,mid,2*c); build(mid+1,b,2*c+1); } void update(int a,int b,int c,int val) { if(e[c].l==a&&e[c].r==b) { e[c].w+=val; return; } int mid=(e[c].l+e[c].r)/2; if(b<=mid) update(a,b,2*c,val); else if(a>mid) update(a,b,2*c+1,val); else { update(a,mid,2*c,val); update(mid+1,b,2*c+1,val); } e[c].w=e[2*c].w+e[2*c+1].w; } int query(int a,int b,int c) { if(e[c].l==a&&e[c].r==b) return e[c].w; int mid=(e[c].l+e[c].r)/2; if(b<=mid) return query(a,b,2*c); else if(a>mid) return query(a,b,2*c+1); else return query(a,mid,2*c)+query(mid+1,b,2*c+1); } int main() { int n; while(scanf("%d",&n)!=EOF) { int i,j,k,sum,x,p,q; build(1,n,1); sum=0; for(i=0;i<n;i++) { scanf("%d",&x); sum+=query(x,n,1); update(x,x,1,1); } p=sum%2; sum=0; build(1,n,1); for(i=0;i<n;i++) { scanf("%d",&x); sum+=query(x,n,1); update(x,x,1,1); } q=sum%2; if(p^q) printf("Impossible\n"); else printf("Possible\n"); } return 0; }
用线段树求出两个排序的逆序数,判断奇偶;同奇同偶输出possible,否则输出impossible
怎么证明,I don't know ,问了同学,告诉我是YY出来的。。