zoukankan      html  css  js  c++  java
  • BZOJ 1176: [Balkan2007]Mokia | CDQ分治

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1176


    题解:

    题目s无用

     其实是CDQ还是能够看出来的,就是怎么做需要考虑考虑

    首先对于一个区间的询问我们可以通过二维前缀和的方式转化成四个前缀询问,这样就可以用树状数组这类数据结构很快维护一维

    然后把操作们按x坐标排序(x是第一维),这样树状数组就只用维护y轴信息即可

    因为我们只用考虑一个序列中前半段时间修改对后半段时间答案的影响,所以树状数组维护一下y轴信息即可

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define M 2000010
    using namespace std;
    int s,w,op,x1,y1,x2,y2,cnt=1,ans[M],t[M],m;
    struct Op
    {
        int type,t,x,y,k,id;
        bool operator < (const Op &b)const
    	{
    	    if (x==b.x && y==b.y) return type<b.type;
    	    if (x==b.x) return y<b.y;
    	    return x<b.x;
    	}
    }p[M],tmp[M];
    inline void AddQuery()
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        p[++cnt].id=++m;p[cnt].t=cnt,p[cnt].x=x1-1;p[cnt].y=y1-1;p[cnt].k=1;p[cnt].type=2;
        p[++cnt].id=m;p[cnt].t=cnt,p[cnt].x=x2;p[cnt].y=y2;p[cnt].k=1;p[cnt].type=2;
        p[++cnt].id=m;p[cnt].t=cnt,p[cnt].x=x1-1;p[cnt].y=y2;p[cnt].k=-1;p[cnt].type=2;
        p[++cnt].id=m;p[cnt].t=cnt,p[cnt].x=x2;p[cnt].y=y1-1;p[cnt].k=-1;p[cnt].type=2;
    }
    inline void Insert(int x,int k)
    {
        for (;x<M;x+=x&-x) t[x]+=k;
    }
    inline int Query(int x)
    {
        int ret=0;
        for (;x;x-=x&-x) ret+=t[x];
        return ret;
    }
    inline void solve(int l,int r)
    {
        if (l==r) return ;
        int mid=l+r>>1,i=l,j=mid+1;
        for (int k=l;k<=r;k++)
    	if (p[k].t<=mid && p[k].type==1)
    	    Insert(p[k].y,p[k].k);
    	else if (p[k].t>mid && p[k].type==2)
    	    ans[p[k].id]+=p[k].k*Query(p[k].y);
        for (int k=l;k<=r;k++)
        {
    	if (p[k].t<=mid && p[k].type==1) Insert(p[k].y,-p[k].k);
    	if (p[k].t<=mid) tmp[i++]=p[k];
    	else tmp[j++]=p[k];
        }
        for (i=l;i<=r;i++)
    	p[i]=tmp[i];
        solve(l,mid);
        solve(mid+1,r);
    }
    int main()
    {
        printf("%d %d
    ",p[0].t,p[1].t);
        scanf("%d%d",&s,&w);
        while (scanf("%d",&op)!=EOF && op!=3)
    	if (op==1)
    	    scanf("%d%d%d",&p[cnt].x,&p[cnt].y,&p[cnt].k),p[cnt].type=1,p[cnt++].t=cnt++;
    	else AddQuery();
        sort(p+1,p+1+cnt);
        solve(1,cnt);
        for (int i=1;i<=m;i++)
    	printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    Transact_SQL小手册(各种sql语句大集合)
    矮人DOS工具箱 使用说明
    window.showModalDialog以及window.open用法简介 (转)
    正则表达式(转)
    Ajax.net用户指南(转)
    Java相关的开源GIS系统
    数据库操作之ODBC
    编译第一个OSG程序时候需要注意的
    OSG编译
    VC 多线程编程(转)
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8098212.html
Copyright © 2011-2022 走看看