扫描线法

SD集训divisors

题目大意:给定一个1~n的排列p,求l<=a,b<=r中pa%pb=0的(a,b)数对个数。

思路:离线操作。对于1~n所有数在n以内的约数个数n/1+n/2+n/3+...+n/n=nlogn,那么我们可以保存下所有的这样成倍数的关系,按左端点排序,然后暴力插入。对于查询也是离线的,按左端点排序,对于关系的左边已经在当前左端点左边的就删掉,然后对于右边的统计相应的和就可以了(用树状数组维护)。

用到的排序和扫描线的思想。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxnode 200005
using namespace std;
struct use{
    int l,r,po;
}ask[maxnode]={0},bei[4000005];
int ci[maxnode]={0},pos[maxnode]={0},ai[maxnode]={0},n,ans[maxnode]={0};
int lowbit(int x){return x&-x;}
int cmp(const use &x,const use &y){return x.l<y.l;}
void add(int x,int y){for (;x<=n;x+=lowbit(x)) ci[x]+=y;}
void get(int x,int y){for (;y;y-=lowbit(y)) ans[x]+=ci[y];}
int main()
{
    freopen("divisors.in","r",stdin);
    freopen("divisors.out","w",stdout);

    int m,i,j,tot=0;
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;++i){scanf("%d",&ai[i]);pos[ai[i]]=i;}
    for (i=1;i<=n;++i)
      for (j=i;j<=n;j+=i){bei[++tot].l=min(pos[i],pos[j]);bei[tot].r=max(pos[i],pos[j]);}
    sort(bei+1,bei+tot+1,cmp);
    for (i=1;i<=tot;++i) add(bei[i].r,1);
    for (i=1;i<=m;++i) {scanf("%d%d",&ask[i].l,&ask[i].r);ask[i].po=i;}
    sort(ask+1,ask+m+1,cmp);j=1;
    for (i=1;i<=m;++i)
    {
        while(j<=tot&&bei[j].l<ask[i].l)
        {
            add(bei[j].r,-1);++j;
        }
        get(ask[i].po,ask[i].r);
    }
    for (i=1;i<=m;++i) printf("%d\n",ans[i]);
}

时间: 2024-08-02 04:53:45

扫描线法的相关文章

【专题】偏序,扫描线

[关键字]偏序,数点,树状数组,线段树,扫描线. 因为涉及多种算法,所以整合到一起. [扫描线] 二维数点,偏序 ★数点问题 ★关于偏序问题的一些总结 一维偏序:排序二分 树状数组 二维偏序:排序扫描线+树状数组(差分)/线段树 三维偏序:排序扫描线+cdq分治+树状数组 排序扫描线+二维数据结构 基本思想是一维扫描线顺序扫描维护差分,一维用数据结构维护区间(线段树维护区间,树状数组差分维护前缀和). [BZOJ3161]布娃娃(扫描线+线段树) BZOJ 4059 Cerc2012 Non-b

Convex(扫描线降维)

Convex Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1838    Accepted Submission(s): 552 Problem Description Your task is very simple. You will get the coordinates of n points in a plane. It

POJ 3667 线段树区间合并

http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html 用线段树,首先要定义好线段树的节点信息,一般看到一个问题,很难很快能确定线段树要记录的信息做线段树不能为了做题而做,首先线段树是一种辅助结构,它是为问题而生的,因而必须具体问题具体分析回忆一下RMQ问题,其实解决RMQ有很多方法,根本不需要用到线段树,用线段树解决RMQ,其实是利用线段树的性质来辅助解决这个问题回忆一下求矩形面积并或周长并的问题,一般使用的是扫描

常见验证码的弱点与验证码识别

http://drops.wooyun.org/tips/141 常见验证码的弱点与验证码识别 insight-labs · 2013/06/08 11:36 0x00 简介 验证码作为一种辅助安全手段在Web安全中有着特殊的地位,验证码安全和web应用中的众多漏洞相比似乎微不足道,但是千里之堤毁于蚁穴,有些时候如果能绕过验证码,则可以把手动变为自动,对于Web安全检测有很大的帮助. 全自动区分计算机和人类的图灵测试(英语:Completely Automated Public Turing t

COGS 896. 圈奶牛

凸包,,,,,,,神奇的凸包2333 本蒟蒻弱势围观了一下Gamham扫描线法,,, 找出左下点,然后把其他点按极角序排一下(极角序相同的可以删掉短的,当然也可以吧短的排到前面) 然后拿一个栈,把新元素压到栈里之前,看看(设栈顶为top)top,top-1和新加入点是不是符合,然后判断一下是不是top点不能再凸包上,然后while搞下去就好了... 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm>

POJ百道水题列表

以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight Moves1101 Gamblers1204 Additive equations 1221 Risk1230 Legendary Pokemon1249 Pushing Boxes 1364 Machine Schedule1368 BOAT1406 Jungle Roads1411 Annive

Codeforces731D 80-th Level Archeology

考虑将两个单词变成有序,我们可以得到一个或者两个旋转次数的区间. 然后考虑将两组单词变成有序,比如[l,mid]和[mid+1,r],对于mid和mid+1这两个单词我们可以求出使他们有序的旋转次数的区间. 然后将这个区间与[l,mid]的区间以及[mid+1,r]的区间求交,就可以得到使[l,r]有序的旋转次数的区间. 上面这个过程我们可以用分治来进行,区间求交可以用扫描线法. #include <bits/stdc++.h> using namespace std; vector<i

常用/常考算法总结

转自tangjz的博客... 基础算法 模拟 搜索 广度优先搜索(BFS) 优化:双向BFS 深度优先搜索(DFS) 优化:折半DFS 迭代加深搜索(IDS) 启发式搜索(Astar) 优化:IDAstar 优化:剪枝.位运算 排序 冒泡排序/选择排序 基数排序/桶排序 计数排序 插入排序/希尔排序 快速排序 归并排序/求逆序对数 堆排序 贪心 分治 二分/三分/n分 cdq分治 倍增/ST 离散化 二分答案 快速幂/十进制快速幂 基础数学 数列求和 泰勒展开 矩阵 矩阵乘法 高斯消元 判断线性

关于鱼眼镜头展图开的一些研究

前言:前段时间在做鱼眼展开的的程序,本来以为超简单,毕竟好多人都已经做过了不是,肯定有许多资料和参考.然而,做什么事情之前都不能眼高手低.我做了好久,还得不出想要的结果,是很烦.前两天导师没办法了给我安排了其他的工作,但我这个还没有得出想要的结果,强迫症的我心里好难受.花两天时间把能想到的全部整理如下,理一理思路,看能不能有所突破. 鱼眼镜头参数是:f=1.5mm,fov=240度 1.常见的三种鱼眼图像 (1)圆形鱼眼图