[2009国家集训队]小Z的袜子(hose)

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

可怕的莫队算法。。。感觉有了这个,是不是可以解决所有的区间查询但是无修改的题目
也许不是最优的,但是O(n*sqrt(n))完全也是可以尝试的。

莫队算法:对于两个区间的查询[l1,r1] ,[l2,r2]如果每增加一个区间元素或者删除,都能做到O(1)的话
那么从[l1,r1]转移到[l2,r2],暴力可以做到|l1-l2|+|r1-r2|,就是manhattan距离
莫队的论文一直没有找到,所以只是大致的了解下,应该是证明出构造出哈密尔顿路径是最优的。
但是可以用manhattan mst来构造,大约会是两倍,然后莫队证明出这样转移的上限是O(n*sqrt(n))。
所以对于这种无修改的区间查询来说
可以先将所有的区间,看成二维平面上的点,求一次manhattan mst,然后根据mst来进行转移
相邻的两个区间的查询转移,暴力解决。
Manhattan MST 这里有
#include   
#include   
#include   
#include 
#include 
#define lowbit(x) (x&(-x)) 
#define LL long long 
using namespace std;  
const int N = 50005;  
struct Point{  
    int x,y,id;  
    bool operator<(const Point p)const{  
        return x!=p.x?x=1;i-=lowbit(i))  
        if(val=0;i--){  
            int pos=lower_bound(b,b+m,a[i])-b+1;   //BIT中从1开始  
            int ans=ask(pos,m);  
            if(ans!=-1)  
                addedge(p[i].id,p[ans].id,dist(i,ans));  
            update(pos,p[i].x+p[i].y,i);  
        }  
    }  
    sort(e,e+tot);  
    for(int i=0;ir1) add(r1+1,r2);
    if(l2>l1) del(l1,l2-1);
    if(r2r1) del(r1+1,r2);
    if(l2>l1) add(l1,l2-1);
    if(r2


你可能感兴趣的:(ACM_数据结构)