hdu3113 Lucky 莫队算法

原创 2015年07月08日 19:59:03
定义记号f(A,B)表示询问区间A,B时的答案
用记号+表示集合的并
利用莫队算法我们可以计算出任意f(A,A)的值
不妨假设A=[l1,r1],B=[l2,r2],C=[r1+1,l21]
容易知道f(A,B)=f(A+B+C,A+B+C)+f(C,C)f(A+C,A+C)f(C+B,C+B)
因此一个询问被拆成四个可以用莫队算法做的询问
直接把上述四个询问拆开即可。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=120005;
int a[maxn];
int cnt[maxn];
typedef long long LL;
LL s1[maxn];
struct pi{
    int l,r,x,id;
}pp[maxn];
int tot;
void  add(int l,int r,int p,int id){
    pp[tot].l=l;
    pp[tot].r=r;
    pp[tot].x=(l-1)/p+1;
    pp[tot].id=id;
    tot++;
}
int cmp(pi a,pi b){
    if(a.x!=b.x) return a.x<b.x;
    return a.r<b.r;
}
int main()
{
    int i,j,n,m,k;
    while(cin>>n){
        memset(cnt,0,sizeof(cnt));
        cin>>k;
        for(i=1;i<=n;i++) scanf("%d",&a[i]);
        LL s=0;
        cin>>m;
        tot=0;
        int p=sqrt(n);
        for(i=0;i<m;i++){
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            add(a,d,p,4*i);
            add(b+1,c-1,p,4*i+1);
            add(a,c-1,p,4*i+2);
            add(b+1,d,p,4*i+3);
        }
        sort(pp,pp+tot,cmp);
        int l=0,r=0;
        for(i=0;i<tot;i++){
            if(i==0){
                for(j=pp[i].l;j<=pp[i].r;j++){
                    cnt[a[j]]++;
                    if(a[j]<=k&&k-a[j]<=30000){
                        int p=cnt[k-a[j]];
                        if(p>0) s+=p;
                    }
                }
            }
            else{
                if(l<pp[i].l){
                    for(j=l;j<pp[i].l;j++){
                        if(a[j]<=k&&k-a[j]<=30000){
                            int p=cnt[k-a[j]];
                            if(p>0) s-=p;
                        }
                        cnt[a[j]]--;
                    }
                }
                else{
                    for(j=l-1;j>=pp[i].l;j--){
                        cnt[a[j]]++;
                        if(a[j]<=k&&k-a[j]<=30000){
                            int p=cnt[k-a[j]];
                            if(p>0) s+=p;
                        }
                    }
                }
                if(r<pp[i].r){
                    for(j=r+1;j<=pp[i].r;j++){
                        cnt[a[j]]++;
                        if(a[j]<=k&&k-a[j]<=30000){
                            int p=cnt[k-a[j]];
                            if(p>0) s+=p;
                        }
                    }
                }
                else{
                    for(j=r;j>pp[i].r;j--){
                        if(a[j]<=k&&k-a[j]<=30000){
                            int p=cnt[k-a[j]];
                            if(p>0) s-=p;
                        }
                        cnt[a[j]]--;
                    }
                }
            }
            s1[pp[i].id]=s;
            l=pp[i].l;
            r=pp[i].r;
        }
        for(i=0;i<m;i++){
            LL ss=s1[4*i]+s1[4*i+1]-s1[4*i+2]-s1[4*i+3];
            printf("%I64d\n",ss);
        }
    }
}


相关文章推荐

hdu 5213 Lucky && 莫队算法的理解

题意: Lucky    Accepts: 34    Submissions: 267  Time Limit: 6000/3000 MS (Java/Others)    Memory L...

hdu 5213 Lucky(莫队算法分块+容斥定理)

Lucky Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Su...

【莫队算法】[HDU5213]Lucky

题目分析:重点是把每个两个区间的询问拆分成四个单个区间的询问。 ans[l][r][u][v]=ans[l][v]-ans[l][u-1]-ans[r+1][v]+ans[r+1][u-1];#in...

hdu 5213 Lucky(容斥+莫队)

题意:给2个区间,从2个区间内各取一个数字,求a_i+a_j = k的对数。 做法:假设区间范围是[x1,y1]和[x2,y2],我们设f(a,b)为区间a,b中等于k的对数总数,那么答案就是f(x...

【HDU】5213 Lucky 【分块(在线算法)】

传送门:【HDU】5213 Lucky 【分块(在线算法)】题目分析: 我来说一下这题的在线做法。首先我们将区间分成n√\sqrt n块,用f[x][y]表示第x块的数和第y块的数相加等于K的对数,...

hdu 3113 Sum of Cubes 数学 枚举 剪枝

数学小题目。

HDU 4638 Group (莫队算法||线段树离散查询)

题目地址:HDU 4638 先写了一发莫队,莫队可以水过。很简单的莫队,不多说。 代码如下:#include #include #include #include #include #i...

HDU4638 Group (线段树,莫队算法)

 题意:给出一个数组,每次查询l,r,看区间内能分成几个连续的数列也即时求求一个区间中连续ID区间的个数。 需要离线处理所有查询。我们从左往右扫描,依次考虑右端点为i的询问,设dp[l]为区间...

HDU - 5145 莫队算法

题意:有n个女生,每个女生都属于一个教室,现在要访问这些女生,就要进入教室,每次进入一个教室只能访问该教室的一个女生,现在要问对于[L,R]之间的女生全部访问,一共有多少种不同的访问教室的方式?思路:...
  • Bahuia
  • Bahuia
  • 2017年04月10日 19:44
  • 111

HDU 4638 Group 莫队算法

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4638 题意:给定一个长度为n的数组,数组中元素为1~n,每次询问一个区间[l, r],求这个区间内可以划...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu3113 Lucky 莫队算法
举报原因:
原因补充:

(最多只允许输入30个字)