hdu 1541 (cdq分治)

Problem Description

Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers want to know the distribution of the levels of the stars.

For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it‘s formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.

You are to write a program that will count the amounts of the stars of each level on a given map.

Input

The first line of the input file contains a number of stars N (1<=N<=15000). The following N lines describe coordinates of stars (two integers X and Y per line separated by a space, 0<=X,Y<=32000). There can be only one star at one point of the plane. Stars are listed in ascending order of Y coordinate. Stars with equal Y coordinates are listed in ascending order of X coordinate.

Output

The output should contain N lines, one number per line. The first line contains amount of stars of the level 0, the second does amount of stars of the level 1 and so on, the last line contains amount of stars of the level N-1.

Sample Input

5
1 1
5 1
7 1
3 3
5 5

Sample Output

1
2
1
1
0

思路:

排序以后把在第二维上分治

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 1e5+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
typedef long long ll;
const ll mod = 1e9+7;
struct node{
    int x,y,id;
    friend bool operator < (node a,node b){
        if(a.x!=b.x) return a.x<b.x;
        return a.y<b.y;
    }
}p[N],a[N];
int f[N];
int ans[N];
void cdq(int l,int r){
    if(l==r) return ;
    int mid=(l+r)>>1;
    cdq(l,mid); cdq(mid+1,r);
    int i=l,j=mid+1,cnt=l;
    while(i<=mid&&j<=r){
        if(p[i].y<=p[j].y){
            a[cnt++]=p[i++];
        }else{
            f[p[j].id]+=(i-l);
            a[cnt++]=p[j++];
        }
    }
    while(i<=mid) a[cnt++]=p[i++];
    while(j<=r){
        f[p[j].id]+=(i-l);
        a[cnt++]=p[j++];
    }
    for(int k=l;k<=r;k++) p[k]=a[k];
}
int main(){
//    ios::sync_with_stdio(false);
//    cin.tie(0); cout.tie(0);
    int n;
    while(~scanf("%d",&n)){
        memset(f,0,sizeof(f));
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;i++){
            int x,y; scanf("%d%d",&x,&y);
            p[i]=node{x,y,i};
        }
        sort(p+1,p+n+1);
        cdq(1,n);
        for(int i=1;i<=n;i++)
            ans[f[i]]++;
        for(int i=0;i<n;i++)
            printf("%d\n",ans[i]);
    }
        return 0;
}

原文地址:https://www.cnblogs.com/wmj6/p/11477436.html

时间: 2024-10-11 16:24:14

hdu 1541 (cdq分治)的相关文章

HDU 5618:Jam&#39;s problem again(CDQ分治+树状数组处理三维偏序)

http://acm.hdu.edu.cn/showproblem.php?pid=5618 题意:-- 思路:和NEUOJ那题一样的.重新写了遍理解了一下,算作处理三维偏序的模板了. 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 using namespace std; 6 #define INF 0x3f3f3f3f 7 #d

HDU 3507 Print Article(CDQ分治+分治DP)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3507 [题目大意] 将长度为n的数列分段,最小化每段和的平方和. [题解] 根据题目很容易得到dp[j]=min(dp[k]+(s[j]-s[k])2),因为是从前往后转移,且决策单调,因此在CDQ分治的同时进行分治DP即可. [代码] #include <cstdio> typedef long long LL; const int N=500005; int n,M,t; LL f[N],

HDU 5730 Shell Necklace(CDQ分治+FFT)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5730 [题目大意] 给出一个数组w,表示不同长度的字段的权值,比如w[3]=5表示如果字段长度为3,则其权值为5,现在有长度为n的字段,求通过不同拆分得到的字段权值乘积和. [题解] 记DP[i]表示长度为i时候的答案,DP[i]=sum_{j=0}^{i-1}DP[j]w[i-j],发现是一个卷积的式子,因此运算过程可以用FFT优化,但是由于在计算过程中DP[j]是未知值,顺次计算复杂度是O(

HDU 5126(stars)四维偏序,cdq分治

题意:给两种操作,进行5万次.操作一:加入一个三维序偶(a,b,c)到集合S里:第二种操作,给两个三维序偶(a1,b1,c1)和(a2,b2,c2),问当前S里有多少个序偶(a,b,c)满足a1<=a<=a2, b1<=b<=b2, c1<=c<=c2.题目保证了a1<=a2,b1<=b2,c1<=c2.所有数在[1,1e9]内 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5126 解法:将操作编号也加入到

hdu 4366 Successor - CDQ分治 - 线段树 - 树分块

Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty and ability.Some times Sean will fire one staff.Then one of the fired man’s Subordinates will replace him whose ability is higher than him and has the h

HDU 5324 Boring Class【cdq分治】

这就是一个三维排序的问题,一维递减,两维递增,这样的问题用裸的CDQ分治恰好能够解决. 如同HDU 4742(三维排序,一个三维都是递增的) 由于最小字典序比較麻烦,所以要从后面往前面做分治.每一个点的dp值表示以这个点为起点.最长能够延伸多长. 本来是想依照Li排序,可是这样做在cdq的时候实在是太难以处理了.所以就依照idx排序.也就是不须要排序. 然后依照Ri排序,对于左边,保证右边的每一个R值大于左边的值.并用树状数组维护Li(由于Li须要递减.所以树状数组恰好能够维护右边的Li小于左边

Boring Class HDU - 5324 (CDQ分治)

Mr. Zstu and Mr. Hdu are taking a boring class , Mr. Zstu comes up with a problem to kill time, Mr. Hdu thinks it’s too easy, he solved it very quickly, what about you guys? Here is the problem: Give you two sequences L1,L2,...,Ln and R1,R2,...,Rn. Y

HDU 5126 stars cdq分治+树状数组

题目链接:点击打开链接 题意: T个case n个操作 1. (x,y,z) 在三维平面的点上增加1 2.询问区间范围内的权值和. 思路: cdq分治套cdq分治,然后套树状数组即可.. #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #inclu

HDU 6183 Color it cdq分治 + 线段树 + 状态压缩

Color it Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Problem Description Do you like painting? Little D doesn't like painting, especially messy color paintings. Now Little B is painting. To prevent him from

hdu 5730 Shell Necklace fft+cdq分治

题目链接 dp[n] = sigma(a[i]*dp[n-i]), 给出a1.....an, 求dp[n]. n为1e5. 这个式子的形式显然是一个卷积, 所以可以用fft来优化一下, 但是这样也是会超时的. 所以可以用cdq分治来优化. cdq分治就是处理(l, mid)的时候, 将dp[l]...dp[mid]对dp[mid+1]...dp[r]做的贡献都算出来. #include <bits/stdc++.h> using namespace std; #define pb(x) pus