bzoj1106: [POI2007]立方体大作战tet

做poi的过程真是苦且艰。。不会。。跳题。。再不会。。再跳。。

这道题其实我以为会很复杂。只会贪心的思想。然后,居然对了。

首先对于任意两个可以配对的石头,它们之间如果存在未配对的石头,何不先让它们配对来减少自己配对的难度呢。

所以有了一个想法,*每次都让最早可以配对的人先配对,配对的方法是统计当前配对石头之间未配对的石头总数,然后一路换过去。

为什么一路换过去是最优。还是要回到刚开始的想法*,既然没办法在当前情况减少自己的匹配步数,那就不得不这样匹配。

事实上,这也是最优的。

至于快速区间查询什么的,树状数组就可以了。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Code:

#include
#include
#define For(i,l,r) for(int (i)=(l);(i)<=(r);(i)++)
using namespace std;
 
const int N=50010*2;
 
int a[N],p[N],n;
 
int lowbit(int k){return k&(-k);}
 
void Add(int k,int d){
    for(;k<=(n<<1);k+=lowbit(k)) a[k]+=d;
} 
 
int Query(int k){
    int ret=0;
    for(;k;k-=lowbit(k)) ret+=a[k];
    return ret;
}
 
int main(){
    int t,ans=0;
    scanf("%d",&n);
    For(i,1,n<<1){
        scanf("%d",&t);
        if(!p[t]){
            p[t]=i;
            Add(i,1);
        }else{
            ans+=Query(i)-Query(p[t]-1)-1;
            Add(p[t],-1);
        }
    }printf("%d",ans);
    return 0;
}


你可能感兴趣的:(Poi)