zoukankan      html  css  js  c++  java
  • [BOI2007]Mokia题解

    这几天学习了cdq分治,来写一篇文章加深理解

    一开始看到这道题,我会二维树状数组!

    w<=2000000
    

    可惜过不得

    然后我们就可以往cdq分治偏序类的问题上想,但我们还要用类似于二维前缀和的方式维护一下,把每一次询问拆成(sum[x_2][y_2]-sum[x_1-1][y_2]-sum[x_2][y_1-1]+sum[x_1-1][y_1-1]),分为四个(ask()),然后就是三位偏序的模板了,数据由于是按时间顺序给的,所以只要归并搞(x)坐标,然后树状数组搞(y)坐标,每次统计一下即可

    放一下代码

    #include<bits/stdc++.h>
    using namespace std;
    struct node
    {
    	int xx,yy,nu,s,qsu;
    }a[1000003],p1[1000003];
    int m,n,tr[2000003],xxx,yyy,xx1,yy1,qsum,ans[200003],typ;
    int lowbit(int x)
    {
    	return x&(-x);
    }
    void add(int x,int num)
    {
    	for(int i=x;i<=n;i+=lowbit(i))
    		tr[i]+=num;
    }
    int ask(int x)
    {
    	int sum=0;
    	for(int i=x;i>0;i-=lowbit(i))
    		sum+=tr[i];
    	return sum;
    }
    void cdq(int l,int r)
    {
    	if(l==r)
    		return;
    	int mid=(l+r)/2,p=l,q=mid+1,tot=l-1;
    	cdq(l,mid),cdq(mid+1,r);
    	while(p<=mid&&q<=r)
    	{
    		if(a[p].xx<=a[q].xx)
    		{
    			if(a[p].s==0)
    				add(a[p].yy,a[p].nu);
    			tot++,p1[tot]=a[p],p++;
    		}
    		else
    		{
    			if(a[q].s!=0)
    				ans[a[q].qsu]+=a[q].s*ask(a[q].yy);
    			tot++,p1[tot]=a[q],q++;
    		}
    	}
    	while(p<=mid)
    	{
    		if(a[p].s==0)
    			add(a[p].yy,a[p].nu);
    		tot++,p1[tot]=a[p],p++;
    	}
    	while(q<=r)
    	{
    		if(a[q].s!=0)
    			ans[a[q].qsu]+=a[q].s*ask(a[q].yy);
    		tot++,p1[tot]=a[q],q++;		
    	}
    	for(int i=l;i<=mid;i++)
    		if(a[i].s==0)
    			add(a[i].yy,-a[i].nu);
    	for(int i=l;i<=r;i++)
    		a[i]=p1[i];
    }
    int main()
    {
    	scanf("%d%d",&n,&n);
    	while(1)
    	{
    		scanf("%d",&typ);
    		if(typ==3)
    			break;		
    		m++;
    		if(typ==1)
    			scanf("%d%d%d",&a[m].xx,&a[m].yy,&a[m].nu);
    		else
    		{
    			scanf("%d%d%d%d",&xx1,&yy1,&xxx,&yyy);
    			qsum++,a[m].xx=xxx,a[m].yy=yyy,a[m].s=1,a[m].qsu=qsum;
    			a[m+1].xx=xx1-1,a[m+1].yy=yyy,a[m+1].s=-1,a[m+1].qsu=qsum;
    			a[m+2].xx=xxx,a[m+2].yy=yy1-1,a[m+2].s=-1,a[m+2].qsu=qsum;
    			a[m+3].xx=xx1-1,a[m+3].yy=yy1-1,a[m+3].s=1,a[m+3].qsu=qsum,m+=3;
    		}
    	}
    	cdq(1,m);
    	for(int i=1;i<=qsum;i++)
    		cout<<ans[i]<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    toj 2819 Travel
    toj 2807 Number Sort
    zoj 2818 Prairie dogs IV
    zoj 1276 Optimal Array Multiplication Sequence
    toj 2802 Tom's Game
    toj 2798 Farey Sequence
    toj 2815 Searching Problem
    toj 2806 Replace Words
    toj 2794 Bus
    css截取字符
  • 原文地址:https://www.cnblogs.com/dzice/p/12213525.html
Copyright © 2011-2022 走看看