zoukankan      html  css  js  c++  java
  • bzoj3262: 陌上花开

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #define maxn 100005
     7 #define maxk 200005
     8 using namespace std;
     9 
    10 int n,k,m,sum[maxk],ans[maxn],sum_[maxn],ans_[maxn];
    11 struct date{
    12     int x,y,z;
    13 }fl[maxn];
    14 struct note{
    15     int y,z,sum,id;
    16 }qs[maxn];
    17 
    18 bool comp1(date x,date y){
    19     if (x.x!=y.x) return x.x<y.x;
    20     if (x.y!=y.y) return x.y<y.y;
    21     return x.z<y.z;
    22 }
    23 
    24 bool comp2(note x,note y){
    25     if (x.y==y.y) return x.z<y.z;
    26     return x.y<y.y;
    27 }
    28 
    29 int lowbit(int x){
    30     return x&(-x);
    31 }
    32 
    33 void add(int x,int y){
    34     for (int i=x;i<=k;i+=lowbit(i)) sum[i]+=y;
    35 }
    36 
    37 int query(int x){
    38     int temp=0;
    39     for (int i=x;i>0;i-=lowbit(i)){
    40         temp+=sum[i];
    41     }
    42     return temp;
    43 }
    44 
    45 void cdq_solve(int l,int r){
    46     if (l==r) return;
    47     int mid=(l+r)/2;
    48     cdq_solve(l,mid),cdq_solve(mid+1,r);
    49     sort(qs+l,qs+mid+1,comp2),sort(qs+mid+1,qs+r+1,comp2);
    50     int i=l,j=mid+1,temp=0;
    51     while (j<=r){
    52         if (i<=mid&&qs[i].y<=qs[j].y) add(qs[i].z,qs[i].sum),i++,temp=i-1;
    53         else ans_[qs[j].id]+=query(qs[j].z),j++;
    54     }
    55     for (int i=l;i<=temp;i++) add(qs[i].z,-qs[i].sum);
    56 }
    57 
    58 int main(){
    59     scanf("%d%d",&n,&k),m=0;
    60     for (int i=1;i<=n;i++) scanf("%d%d%d",&fl[i].x,&fl[i].y,&fl[i].z);
    61     sort(fl+1,fl+n+1,comp1);
    62 //    for (int i=1;i<=n;i++) printf("%d %d %d
    ",fl[i].x,fl[i].y,fl[i].z);
    63     memset(sum,0,sizeof(sum));
    64     memset(ans,0,sizeof(ans));
    65     memset(ans_,0,sizeof(ans_));
    66     for (int i=1;i<=n;i++){
    67         if (fl[i].x==fl[i-1].x&&fl[i].y==fl[i-1].y&&fl[i].z==fl[i-1].z){
    68             sum_[m]=++qs[m].sum;
    69         }else{
    70             qs[++m].sum=1,qs[m].y=fl[i].y,qs[m].z=fl[i].z,qs[m].id=m;
    71             sum_[m]=qs[m].sum;
    72         }
    73     }
    74     cdq_solve(1,m);
    75     for (int i=1;i<=m;i++) ans[ans_[i]+sum_[i]-1]+=sum_[i];
    76     for (int i=0;i<n;i++) printf("%d
    ",ans[i]);
    77     return 0;
    78 }
    View Code

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3262

    题目大意:有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),又三个整数表示。现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb。显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。

    输入格式:第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。

    以下N行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性。
    输出格式:包含N行,分别表示评级为0...N-1的每级花的数量。
     
    做法:三维,据说可以用树套树来写(这个以后再尝试写一发),然后这题正解是传统的cdq分治+排序+树状数组,设花的三个属性为x,y,z,我们将花按x为第一关键字,y为第二关键字,z为第三关键字排序,将属性完全相同的缩成一朵花即可,同时维护sum数组,即属形为(x,y,z)的个数,所以在维护树状数组的时候不能+1,而应该+sum[x]。排序后,后面的花只可能会被前面的花所影响,因为在该花后面的花x都比该花大,我们便能想到用cdq分治。
    想到这点后,对于合并两个区间信息的问题,我们考虑两个区间分别按y坐标排序,依次第一个区间中的花将z坐标加入树状数组,并及时维护第二个区间中的花的答案,这过程用两个指针维护即可。
    cdq分治+树状数组
  • 相关阅读:
    程序11
    程序9
    程序10
    程序8
    提示框
    程序6
    莫名其妙的“网线未连接”
    UI自动化测试笔记(2)
    UI自动化测试笔记(1)
    三年开发项目经验总结
  • 原文地址:https://www.cnblogs.com/OYzx/p/5509988.html
Copyright © 2011-2022 走看看