【BZOJ 3192】【JLOI 2013】アイテムシミュレーションの削除


#include <stdio.h>
int main()
{
	puts("         ");
	puts("http://blog.csdn.net/vmurder/article/details/43064295");
}

問題:
コード内のinitは現在の左スタックトップ番号です.
各アイテムにマッピングしてソートし、暴力を最大から最小にスキャンします.
2つのシーケンス番号の間に存在するアイテムの数(ツリー配列、セグメントツリーで)を加算するたびに、アイテムを削除してinitを変更します.
どうせ水が爆発するまで、むやみにやればいい.
コード:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
using namespace std;
struct LSH
{
	int x,id;
	bool operator < (const LSH &a)const{return x<a.x;}
	LSH(int _x=0,int _id=0):x(_x),id(_id){}
}seq[N];
int n,m,init;

int fw[N];
inline void add(int x,int w){for(;x<=n;x+=(x&-x))fw[x]+=w;}
inline int query(int x){int ans=0;for(;x;x-=(x&-x))ans+=fw[x];return ans;}

int main()
{
	int i,j,k;
	int a,b,c;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a);
		seq[i]=LSH(-a,n-i+1);
	}
	init=n;
	for(i=1;i<=m;i++)
	{
		scanf("%d",&a);
		seq[i+n]=LSH(-a,i+n);
	}
	n+=m;
	sort(seq+1,seq+n+1);
	//     
	// init     ,          
	for(i=1;i<=n;i++)add(i,1);

	long long ans=0;
	for(i=1;i<=n;i++)
	{
		int d=seq[i].id;
		if(init<=d)
		{
			int t=query(d-1)-query(init);
			if(t>0)ans+=t;
			add(d,-1),init=d;
		}
		else {
			int t=query(init)-query(d);
			if(t>0)ans+=t;
			add(d,-1),init=d;
		}
	}
	cout<<ans<<endl;
	return 0;
}