首页 > 其他分享 >IOI 2007 Pairs

IOI 2007 Pairs

时间:2023-11-21 12:11:18浏览次数:59  
标签:Pairs NN int geq pos i64 2007 IOI

IOI 2007 Pairs
可以考虑三个情况:
若B=1:
这其实好像没什么好说的?lower_bound就可以轻轻松松30分
code:

void solve1(){
    for(int i=0;i<N;i++){
        std::cin>>a[i];
    }
    sort(a,a+N);
    i64 ans=0;
    for(int i=0;i<N;i++){
        int lst=lower_bound(a,a+N,a[i]-D)-a;
        ans+=i-lst;
    }
    std::cout<<ans<<'\n';
}

若B=2:
这就需要一些观察了:
考虑分成四个式子可以发现到 $(x,y)$到$(a,b)$的距离为:
if $x-a \geq 0$  and  $y-b \geq 0$, $dis = x-a+y-b = (x+y)-(a+b)$
if $x-a < 0$  and  $y-b \geq 0$, $dis = a-x+y-b = (a-b)-(x-y)$
if $x-a \geq 0$  and  $y-b < 0$, $dis = x-a+b-y = (x-y)-(a-b)$
if $x-a < 0$  and  $y-b < 0$, $dis = a-x+b-y = (a+b)-(x+y)$
$(x+y,x-y)$ 和 $(a+b,a-b)$的切比雪夫距离 $max(|(x+y)-(a+b)|, |(x-y)-(a-b)|)$ = $(x,y)$ 和 $(a,b)$ 的曼哈顿距离
结论:转换成$(x+y,x-y)$然后求矩阵$[x+y-d,x-y+d]$ 至 $[x+y,x-y+d]$ 的和。
维护双指针然后利用一个树状结构来维护区间值就可以了.
code:
i64 tr[NN<<1];
void update(int x,i64 v){
    x+=NN;
    for(;x;x=x/=2){ tr[x]+=v;}
}
i64 get(int x,int y){
    x+=NN; y+=NN;
    i64 res=0;
    while(x<=y){
        if(x%2==1) res+=tr[x++];
        if(y%2==0) res+=tr[y--];
        x/=2; y/=2;
    }
    return res;
}
void solve2(){
    vector<int> pos[75000*2+500];
    i64 ans=0;
    for(int i=0;i<N;i++){
        std::cin>>x[i]>>y[i];
        pos[x[i]+y[i]].push_back(x[i]-y[i]+M);
    }
    for(int i=2;i<=2*M;i++){
        for(auto &u:pos[i]){
            ans+=get(max(0,u-D),min(2*M,u+D));
            update(u,1);
        }
        if(i-D<=0) continue;
        for(auto &u:pos[i-D]) update(u,-1);
    }
    std::cout<<ans<<'\n';
}

 


  若B=3: 我本人是不太会的但是看了别人的讲解,大概是拆成八个式子然后利用数值很小的原因,开桶然后就利用类似B=2的方式去解。

以下代码只能过B=1/2:
有时间的话我会修改成B=1/2/3
/*
Problem: IOI 2007 Pairs
When:    2023-11-16 14:54:19
Author:  Ning07
*/
 
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
 
constexpr int NN=2e5;
int N,B,M,D,a[NN],x[NN],y[NN];
 
void solve1(){
    for(int i=0;i<N;i++){
        std::cin>>a[i];
    }
    sort(a,a+N);
    i64 ans=0;
    for(int i=0;i<N;i++){
        int lst=lower_bound(a,a+N,a[i]-D)-a;
        ans+=i-lst;
    }
    std::cout<<ans<<'\n';
}
i64 tr[NN<<1];
void update(int x,i64 v){
    x+=NN;
    for(;x;x=x/=2){ tr[x]+=v;}
}
i64 get(int x,int y){
    x+=NN; y+=NN;
    i64 res=0;
    while(x<=y){
        if(x%2==1) res+=tr[x++];
        if(y%2==0) res+=tr[y--];
        x/=2; y/=2;
    }
    return res;
}
void solve2(){
    vector<int> pos[75000*2+500];
    i64 ans=0;
    for(int i=0;i<N;i++){
        std::cin>>x[i]>>y[i];
        pos[x[i]+y[i]].push_back(x[i]-y[i]+M);
    }
    for(int i=2;i<=2*M;i++){
        for(auto &u:pos[i]){
            ans+=get(max(0,u-D),min(2*M,u+D));
            update(u,1);
        }
        if(i-D<=0) continue;
        for(auto &u:pos[i-D]) update(u,-1);
    }
    std::cout<<ans<<'\n';
}
void solve3(){
    std::cout<<"?\n";
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
 
    std::cin>>B>>N>>D>>M;
    if(B==1) solve1();
    else if(B==2) solve2();
    else if(B==3) solve3();
}

$+M$是为了更好地询问, $y-d$不会成负数

标签:Pairs,NN,int,geq,pos,i64,2007,IOI
From: https://www.cnblogs.com/yonglicp/p/17846334.html

相关文章

  • [SHOI2007] 园丁的烦恼
    [SHOI2007]园丁的烦恼题目背景很久很久以前,在遥远的大陆上有一个美丽的国家。统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草。有一天国王漫步在花园里,若有所思,他问一个园丁道:“最近我在思索一个问题,如果我们把花坛摆成六个六角形,那么……”......
  • P1098 [NOIP2007 提高组] 字符串的展开(总结)
    P1098[NOIP2007提高组]字符串的展开http://ww.luogu.com.cn/problem/P1098注意字符中的数字是默认小于字母的。所以要对数字做特判。#include<iostream>#include<string>usingnamespacestd;intmain(){ intp1,p2,p3; cin>>p1>>p2>>p3; strings; cin......
  • IOI 2007 Miners
    三种食物,两个矿地。每个矿地会记得最靠近的三种食物,每一次给他们一个新的食物时,答案会加上有多个不同的食物。 求答案的最大值。 很简单的dp: dp[i][a1][a2][b1][b2]表示当前已经分了i个食物,a的上两个食物为a1,a2,b的上两个食物为b1,b2。那么转移状态为:让s[i]表示当......
  • CF1542E2 Abnormal Permutation Pairs (hard version) 题解
    怎么会有这么离谱的题目啊。【模板】前缀和优化dp。思路考虑一个基本的东西。由于要求字典序的限制。我们可以枚举最长公共前缀计算。考虑如何求长度为\(i\)的排列有\(j\)个逆序对的数量。设\(dp_{i,j}\)。\[dp_{i,j}=\sum_{k=0}^{i-1}dp_{i-1,j-k}\]就是枚举新的......
  • P1129 [ZJOI2007] 矩阵游戏
    挺喜欢的一题。首先我们很容易观察到一个性质:每一行和每一列上的黑色方格的数量是不变的,只能改变它在那一行和那一列的排列顺序。由此若是有某一行或某一列上没有黑色方格,直接输出No即可。此时我们考虑的情况就是每一行和每一列上至少都会有一个黑色方格。这时有一个结论:若有......
  • [题解] P5901 [IOI2009] Regions
    P5901[IOI2009]Regions给你一棵树,每个点有颜色\(h_i\)。多次询问,每次询问有多少对\((u,v)\)满足\(u\)是\(v\)的祖先且\(u\)的颜色是\(r_1\)且\(v\)的颜色是\(r_2\)。\(n,q\le2\times10^5,h_i\le2.5\times10^4\)。总颜色数一定,考虑对颜色的出现次......
  • 【洛谷 P4414】[COCI2006-2007#2] ABC 题解(排序)
    [COCI2006-2007#2]ABC题面翻译【题目描述】三个整数分别为。这三个数字不会按照这样的顺序给你,但它们始终满足条件:。为了看起来更加简洁明了,我们希望你可以按照给定的顺序重新排列它们。【输入格式】第一行包含三个正整数,不一定是按这个顺序。这三个数字都小于或等于。第二行包......
  • 2007-多媒体教学的基础知识
    一、什么是多媒体教学?   多媒体教学是指在教学过程中,根据教学目标和教学对象的特点,通过教学设计,合理选择和运用现代教学媒体,并与传统教学手段有机组合,共同参与教学全过程,以多种媒体信息作用于学生,形成合理的教学过程结构,达到最优化的教学效果。   多媒体教学在八十年代已......
  • Luogu P8518 [IOI2021] 分糖果
    题目链接 做这道题本意是为了补CCPC秦皇岛热身赛C,也就是2022CCPC华为云计算挑战赛 机器人那题先考虑一个盒子怎么做,并且不考虑限制那样的话可以得到时刻和盒子内球的数量的图像,考虑由这个不加限制的图像推出加上限制的实际答案完整的图像一定是极大值极小值交错,考虑两个相......
  • IOI 2007 Flood
    有一些墙壁链接(ax,ay),(bx,by)每次若有墙壁的两边一个有水,一个为空,墙壁就破了然后水开始充了起来找出最后还存在的墙壁 首先我们可以看出来墙壁的两边是可以用节点表示的我们需要合并一些区间什么的,听说这一题有些人利用对偶图来求但是我不会可以自己想想怎么样合并/哪......