#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出来的。。