• [bzoj1807] [Ioi2007]Pairs 彼此能听得见的动物对数


      这题挺神的...膜了半天claris的题解还有官方题解。。

      一维随便搞,

      二维的话就旋转坐标系,把原来的点(x,y)变成(x+y,x-y),把曼哈顿距离变成切比雪夫距离。然后排序后扫描线,树状数组维护。

      三维的话.....官方题解是旋转坐标系后直接三维树状数组?(吓哭

            Claris的题解说只要旋转后两维,预处理一波前缀和就行了....具体推一下就知道了。

      三维官方题解复杂度是nlog^3n,Claris做法是nm。。劲啊

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll long long
     6 using namespace std;
     7 const int maxn=100233;
     8 int x[maxn];
     9 struct zs{int x,y,z;}a[maxn];
    10 ll ans;
    11 int i,j,k,n,m,D,id,M;
    12  
    13 bool cmp(zs a,zs b){return a.x<b.x;}
    14 int ra;char rx;
    15 inline int read(){
    16     rx=getchar(),ra=0;
    17     while(rx<'0'||rx>'9')rx=getchar();
    18     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    19 }
    20  
    21 inline void run1(){
    22     register int i,l=1;
    23     for(i=1;i<=n;i++)x[i]=read();
    24     sort(x+1,x+1+n);
    25     for(i=2;i<=n;ans+=i-l,i++)while(x[i]-x[l]>D)l++;
    26 }
    27  
    28 int t[75233<<1];
    29 inline void del(int x){while(x<=M)t[x]--,x+=x&-x;}
    30 inline void add(int x){while(x<=M)t[x]++,x+=x&-x;}
    31 inline ll query(int x){
    32     if(x<=0)return 0;
    33     if(x>M)x=M;
    34     ll sm=0;
    35     while(x)sm+=t[x],x-=x&-x;
    36     return sm;
    37 }
    38 inline void run2(){
    39     register int i;
    40     for(i=1;i<=n;i++)j=read(),k=read(),a[i].x=j+k,a[i].y=j-k+m;
    41     sort(a+1,a+1+n,cmp);int top=1;
    42     for(i=1;i<=n;i++){
    43         while(a[top].x+D<a[i].x)del(a[top].y),top++;
    44         ans+=query(a[i].y+D)-query(a[i].y-D-1),
    45         add(a[i].y);
    46     }
    47 }
    48  
    49 ll mp[77][77<<1][77<<1];
    50 inline ll getsm(int x,int x1,int y1,int x2,int y2){
    51     if(x1<1)x1=1;if(y1<1)y1=1;
    52     if(x2>M)x2=M;if(y2>M)y2=M;
    53     return mp[x][x2][y2]-mp[x][x1-1][y2]-mp[x][x2][y1-1]+mp[x][x1-1][y1-1];
    54 }
    55 inline void run3(){
    56     register int i,j,k;int x;ll tmp=0;
    57     for(i=1;i<=n;i++)a[i].x=read(),j=read(),k=read(),a[i].y=j+k,a[i].z=j-k+m;
    58     sort(a+1,a+1+n,cmp);
    59     for(i=1;i<=n;){
    60         x=a[i].x;
    61         for(j=i;a[j+1].x==x;j++);
    62         while(i<=j)mp[x][a[i].y][a[i].z]++,i++;
    63         for(j=1;j<=M;j++)for(k=1;k<=M;k++)mp[x][j][k]+=mp[x][j-1][k]+mp[x][j][k-1]-mp[x][j-1][k-1];
    64     }
    65     for(i=1;i<=n;i++){
    66         for(j=a[i].x+1;j<=m&&j-a[i].x<=D;j++)
    67             k=D-(j-a[i].x),ans+=getsm(j,a[i].y-k,a[i].z-k,a[i].y+k,a[i].z+k);
    68         tmp+=getsm(a[i].x,a[i].y-D,a[i].z-D,a[i].y+D,a[i].z+D)-1;
    69     }
    70     tmp>>=1;
    71     ans+=tmp;
    72 }
    73 int main(){
    74     id=read(),n=read(),D=read(),m=read();M=m<<1;
    75     if(D>=m*id){printf("%lld
    ",(ll)n*(n-1)/2);}
    76     if(id==1)run1();
    77     if(id==2)run2();
    78     if(id==3)run3();
    79     printf("%lld
    ",ans);
    80     return 0;
    81 }
    View Code

  • 相关阅读:
    数据库插入数据返回当前主键ID值方法
    兼容SQLSERVER、Oracle、MYSQL、SQLITE的超级DBHelper
    C# listview 单击列头实现排序 <二>
    C# ListView点击列头进行排序
    MessageBox.Show()的各种用法
    QT 删除文件指定目录
    hihoCoder 1015 KMP算法
    hiho一下 第五十周 (求欧拉路径)
    hdu
    hiho一下 第四十九周 欧拉路
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5597844.html
Copyright © 2020-2023  润新知