zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:蔬菜(二维莫队)

    题目描述

      小$C$在家中开垦了一块菜地,可以抽象成一个$r imes c$大小的矩形区域,菜地的每个位置都种着一种蔬菜。秋天到了,小$C$家的菜地丰收了。
      小$C$拟定了$q$种采摘蔬菜的计划,计划采摘区域是菜地的一个子矩形,你需要帮助他计算每种计划的美味度,美味度等于每种蔬菜在采摘区域出现次数的平方和。


    输入格式

    第一行三个正整数$r,c,q$。
    接下来$r$行每行$c$个正整数,第$i+1$行第$j$个数为$a_i,j$,表示每个位置的蔬菜种类。
    接下来$q$行,每行$4$个正整数$x_0,y_0,x_1,y_1$表示采摘区域的左上角和右下角的位置。


    输出格式

    输出$q$行,每行一个整数,第$i$行的数表示第$i$组采摘计划的答案。


    样例

    样例输入:

    3 4 8
    1 3 2 1
    1 3 2 4
    1 2 3 4
    1 1 2 2
    1 1 2 1
    1 1 3 4
    1 1 1 1
    2 2 3 3
    2 2 3 4
    1 1 3 3
    2 4 3 4

    样例输出:

    8
    4
    38
    1
    8
    12
    27
    4


    数据范围与提示

    对于$100\%$的数据,$r,cleqslant 200,qleqslant 100,000,a_i,jleqslant {10}^9$。
    $ullet Subtask 1(23pts):r,cleqslant 100,qleqslant 1,000$。
    $ullet Subtask 2(15pts):r,cleqslant 100,qleqslant 10,000$。
    $ullet Subtask 3(17pts):r,cleqslant 200,qleqslant 50,000$。
    $ullet Subtask 4(20pts):$蔬菜种类数不超过$200$。
    $ullet Subtask 5(25pts):$无特殊限制


    题解

    正解是四维偏序,说白了就是$CDQ$套$CDQ$。

    然而可以用二维莫队水,队爷就是$NB$。

    推销一波二维莫队:二维莫队(离线)

    对于可怕的数据范围,直接离散化搞就好了。

    说了二维莫队就没啥好说的了,在这里就想再说三点:

      $alpha.$对于一个知识点,你比别人多学或者是早学不是错;哪怕你是知道这次要考什么,因为即便告诉别人用什么解法,不会还是不会;而对于有人说的认为复杂度不对,也可以归结为不会——$to$可爱的同桌。

      $eta.$这道题的数据有点水,所以打一个假的二维莫队也可以水过去,有的人知道,有的人不知道,在此提醒一下,这样排序是不对的:

    bool cmp(rec a,rec b){return (a.x0==b.x0)?((a.x2==b.x2)?((a.y0==b.y0)?a.y2<b.y2:a.y0<b.y0):a.x2<b.x2):a.x0<b.x0;}
    

      但是的确可以水过去,正确的方法应该是:

    int sqrr=sqrt(r);sqrc=sqrt(c);
    bool cmp(rec a,rec b){return a.x0/sqrr==b.x0/sqrr?(a.y0/sqrc==b.y0/sqrc?(a.x2/sqrr==b.x2/sqrr?a.y2/sqrc<b.y2/sqrc:a.x2<b.x2):a.y0<b.y0):a.x0<b.x0;}
    

      $gamma.$最好利用公式统计答案,即${x+1)}^2-x^2$,因为在种类过多的时候肯定会卡死的。

    时间复杂度:$Theta(qlog q+q imes nsqrt{n})$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    struct rec{int x0,y0,x2,y2,pos,id;}e[100001];
    int r,c,q;
    int sqrr,sqrc;
    int Map[201][201],zls;
    int s[40001];
    map<int,int> mp;
    long long ans[100001];
    int uu,dd,ll,rr;
    bool cmp(rec a,rec b){return a.x0/sqrr==b.x0/sqrr?(a.y0/sqrc==b.y0/sqrc?(a.x2/sqrr==b.x2/sqrr?a.y2/sqrc<b.y2/sqrc:a.x2<b.x2):a.y0<b.y0):a.x0<b.x0;}
    int ask(int x){return 2*x+1;}
    void upd(int id,int l,int r,bool b,bool w){for(int i=l;i<=r;i++)if(b)if(w){ans[0]+=ask(s[Map[id][i]]);s[Map[id][i]]++;}else{s[Map[id][i]]--;ans[0]-=ask(s[Map[id][i]]);}else if(w){ans[0]+=ask(s[Map[i][id]]);s[Map[i][id]]++;}else{s[Map[i][id]]--;ans[0]-=ask(s[Map[i][id]]);}}
    int main()
    {
    	scanf("%d%d%d",&r,&c,&q);
    	sqrr=sqrt(r);sqrc=sqrt(c);
    	for(int i=1;i<=r;i++)
    		for(int j=1;j<=c;j++)
    		{
    			scanf("%d",&Map[i][j]);
    			if(!mp[Map[i][j]])Map[i][j]=mp[Map[i][j]]=++zls;
    			else Map[i][j]=mp[Map[i][j]];
    		}
    	for(int i=1;i<=q;i++)
    	{
    		scanf("%d%d%d%d",&e[i].x0,&e[i].y0,&e[i].x2,&e[i].y2);
    		e[i].id=i;
    	}
    	sort(e+1,e+q+1,cmp);
    	ll=rr=e[1].x0;
    	uu=dd=e[1].y0;
    	s[Map[ll][uu]]++;
    	ans[0]=1;
    	for(int i=1;i<=q;i++)
    	{
    		while(uu>e[i].y0)upd(--uu,ll,rr,0,1);
    		while(uu<e[i].y0)upd(uu++,ll,rr,0,0);
    		while(dd<e[i].y2)upd(++dd,ll,rr,0,1);
    		while(dd>e[i].y2)upd(dd--,ll,rr,0,0);
    		while(ll>e[i].x0)upd(--ll,uu,dd,1,1);
    		while(ll<e[i].x0)upd(ll++,uu,dd,1,0);
    		while(rr<e[i].x2)upd(++rr,uu,dd,1,1);
    		while(rr>e[i].x2)upd(rr--,uu,dd,1,0);
    		ans[e[i].id]=ans[0];
    	}
    	for(int i=1;i<=q;i++)printf("%lld
    ",ans[i]);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    Linux目录操作
    图形库
    Mybatis两表连接(一对一)
    ssm图片上传到数据库
    ajax函数实例
    html、css基础
    HDU 1213 How Many Tables
    HTML5简介
    在script中创建标签的三种方式
    html css js jq问题总结
  • 原文地址:https://www.cnblogs.com/wzc521/p/11577220.html
Copyright © 2011-2022 走看看