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;
    }
    
    
  • 相关阅读:
    oracle中scott/tiger、sys、SYSDBA、system都是什么用
    选择ORACLE数据库字符集
    如何给oracle账户解锁
    nodejs_100个实例(3)_文件读取
    nodejs+express+mongodb简单实现注册登录
    ECharts之类型map(省级,地级市)附(世界地图、中国、省份、地级市地图Json文件)
    nodejs_100个实例(2)
    nodejs_100个实例(1)
    nodejs学习过程2之相关网站2
    nodejs学习过程2之相关网站
  • 原文地址:https://www.cnblogs.com/dzice/p/12213525.html
Copyright © 2011-2022 走看看