首页 > 编程语言 >[AT_ABC106_D]题解(C++)

[AT_ABC106_D]题解(C++)

时间:2023-08-18 19:11:52浏览次数:37  
标签:列车 ch int 题解 C++ leq sim ABC106 dp

Part I Preface

Part II Sketch

  • 给定正整数 \(n, m, q\)。
  • 接下来给定 \(m\) 组 \(x_i, y_i\),表示一列列车的起始站和终点站。
  • 在接下来给定 \(q\) 组 \(l_i, r_i\)。
  • 对于每组询问,回答有多少 \(x_i \geq l_i \operatorname{and} y_i \leq r_i\),即有多少列列车的全程都包含在 \(l_i, r_i\) 间。
  • \(1 \leq n \leq 500\)。
  • \(1 \leq m \leq 200000\)。
  • \(1 \leq q \leq 100000\)。
  • \(1 \leq x_i \leq y_i \leq n\)。
  • \(1 \leq l_i \leq r_i \leq n\)。

Part III Analysis

简单思考不难发现, \(l_i\sim r_i\) 中的列车数量即为 \(l_i\sim r_i - 1\) 中的列车数量加上 \(l_i + 1\sim r_i\) 中的列车数量。但是 \(l_i + 1\sim r_i - 1\) 中的列车被算了两次,重复了,我们要去掉一个。

所以 \(l_i\sim r_i\) 中列车的数量就等于 \(l_i\sim r_i - 1\) 中的列车数量加上 \(l_i + 1\sim r_i\) 中列车的数量减去 \(l_i + 1\sim r_i - 1\) 中列车的数量。若用 \(dp(i, j)\) 表示 \(i\sim j\) 中列车的数量,状态转移方程即为:

\[dp(i, j) = dp(i, j - 1) + dp(i + 1, j) - dp(i + 1, j - 1) \]

输入时,每次输入一列列车的起始站和终点站 \(x_i, y_i\) 时,我们直接给 \(dp(x_i, y_i)\) 自增即可,这就是初始状态。最终输出每个 \(dp(l_i, r_i)\) 即可。

注意因为我们每次计算时都用到了 \(i + 1\) 这一层的信息,所以我们枚举 \(i\) 时需要从 \(n\sim 1\) 进行遍历。

Part IV Code

#include <bits/stdc++.h>
using namespace std;
const int N = 505;
inline int read(){
    int s = 0, w = 1;
    char ch = getchar();
    while(!isdigit(ch)){
        if(ch == '-') w = -1;
        ch = getchar();        
    }
    while(isdigit(ch)){
        s = s * 10 + ch - '0';
        ch = getchar();
    }
    return s * w;
}
inline void write(int x){
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
int n, m, q;
int dp[N][N];
int main(){
    n = read(), m = read(), q = read();
    while(m--) dp[read()][read()]++;
    for(int i = n; i >= 1; i--)
        for(int j = i; j <= n; j++)
            dp[i][j] += dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1];
    while(q--) write(dp[read()][read()]), putchar('\n');
    return 0;
}

标签:列车,ch,int,题解,C++,leq,sim,ABC106,dp
From: https://www.cnblogs.com/InftySky/p/AT-ABC106-DTJ.html

相关文章

  • [AT_ABC106_B]题解(C++)
    PartIPreface原题目\(\text{(Luogu)}\)原题目\(\text{(AtCoder)}\)PartIISketch给定一个正整数\(N\)。求出\(1\simN\)所有因数个数为\(8\)的数的个数。PartIIIAnalysis先输入\(N\)。遍历\(1\simN\)的每个数,记录每个数的因数个数。若因数个数等于\(8\)......
  • [AT_ABC106_A]题解(C++)
    PartIPreface原题目$\text{(Luogu)}$原题目$\text{(AtCoder)}$PartIISketch给定整数$a,b$,输出$(a-1)\times(b-1)$。$2\leqa,b\leq100$。PartIIIAnalysis运用小学知识,进行平移,把几块地拼接在一起。不难看出长为$a-1$,宽为$b-1$,面积为$(a-1)\tim......
  • c++ 占位符和序列化
    1#include<nlohmann/json.hpp>2#include<iostream>3#include<iomanip>45usingjson=nlohmann::json;67intmain()8{9std::cout<<std::setw(4)<<json::meta()<<std::endl;10}https://json.n......
  • [AGC061C] First Come First Serve 题解
    题意有两个长度为\(n\)的正整数列\(A,B\)。表示数\(i\)可以填到\(A_i\)或\(B_i\)两个位置中的一个。问删去空位之后可以形成的排列种数。(\(1\len\le5\times10^5\),\(A_i,B_i\)取遍\(\left[1,2n\right]\))。题解首先可以发现填数的方案数为\(2^n\),发现会计算......
  • C++快速入门 第四十二讲:链接和作用域
    与作用域有关的另一个概念是链接,当同时编译多个文件时,每个源文件被称为一个翻译单元,在某一个翻译单元里定义的东西在另一个翻译单元里使用正是链接发挥作用的地方。存储类(storageclass):每个变量都有一个存储类,它决定着程序将把变量的值储存在计算机的什么地方、如何存储、以及变......
  • C++快速入门 第四十三讲:链接和作用域2
    1header.h文件23#ifndefHEADER_H4#defineHEADER_H56unsignedlongreturnFactorial(unsignedshortnum);7staticconstunsignedshortheaderNum=5;//定义静态恒定值的全局变量89#endif1011that.cpp文件:1213#include"header.h"14uns......
  • C++快速入门 第四十五讲:类模板
    类模板与函数模板非常相似,同样是先由你编写一个类的模板,再由编译器在你第一次使用这个模板时生成的实际代码。实例:栈的出入栈1#include<iostream>2#include<string>34template<classT>5classStack//栈类6{7public:8Stack(unsignedintsize=......
  • C++快速入门 第四十四讲:函数模板swap使用
    泛型编程技术支持程序员创建函数和类的蓝图(即模板,template),而不是具体的函数和类。标准模板库STL(StandardTemplateLibrary),STL库是泛型编程技术的经典之作,它包含了许多非常有用的数据类型和算法。当拥有一个模板时,编译器将根据模板自动创建一个函数,该函数会使用正确的数据类型......
  • C++快速入门 第四十六讲:内联模板
    内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。编译时类似宏替换,使用函数体替换调用处的函数名。(在程序中,调用其函数时,该函数在编译时被替换,而不是像一般函数那样是在运行时被调用)实例:栈1#include<iostream>2#include<string>34template<class......
  • C++快速入门 第四十七讲:容器和算法
    C++标准库提供的向量(vector)类型从根本上解决了数组先天不足的问题(内存固定,如果不用那么多内存编译器也会为其分配)我们用不着对一个向量能容纳多少元素做出限定,因为向量可以动态地随着你往它里面添加元素而无限增大。还可以用它的size()方法查知某给定向量的当前长度(即包含的元素......