algorithm_2024/src/P2822/P2822_debug.cpp
2024-10-11 05:38:08 +00:00

136 lines
3.4 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// #define NDEBUG //切换release和debug版本
#include <cctype>
#include <iostream>
#include <algorithm>
#include <type_traits>
#include <sstream>
using ull = unsigned long long;
template<class T,size_t size>
struct Array{
constexpr Array(){};
constexpr Array(const std::initializer_list<T> list){
std::copy(list.begin(),list.end(),arr);
}
#ifdef NDEBUG
#define NDB_NOEXCEPT noexcept
#define NDB_CONSTEXPR constexpr
#else
#define NDB_NOEXCEPT
#define NDB_CONSTEXPR
#endif
NDB_CONSTEXPR T& operator[](const size_t n)NDB_NOEXCEPT{
// static_assert(noexcept(Array::operator[](0)), "isn't noexcept");
#ifndef NDEBUG
if(n>=size){
std::ostringstream err_oss;
err_oss<<"\n[array_size]: "<<size<<"\n[Your index]: "<<n<<'\n';
throw std::runtime_error(err_oss.str());
}
#endif
return arr[n];
}
struct Iterator{
constexpr Iterator(const size_t n,T *const p)noexcept:now{n},p{p}{}
bool operator!=(const Iterator &that)const noexcept{
return this->now!=that.now;
}
NDB_CONSTEXPR T& operator*()const NDB_NOEXCEPT{
#ifndef NDEBUG
if(now>=size){
std::ostringstream err_oss;
err_oss<<"[array_size]: "<<size<<" [Your index]: "<<now<<'\n';
throw std::runtime_error(err_oss.str());
}
#endif
return p[now];
}
constexpr Iterator& operator++()noexcept{
now++;
return *this;
}
constexpr Iterator& operator--()noexcept{
now--;
return *this;
}
constexpr Iterator operator--(int)noexcept{
auto old = *this;
now--;
return old;
}
private:
size_t now;
T *const p;
};
constexpr Iterator begin()noexcept{
return Iterator(0,arr);
}
constexpr Iterator end()noexcept{
return Iterator(size,arr);
}
private:
T arr[size];
};
static const size_t max_n {(size_t)2e3+5};
ull k, t, n, m;
Array<Array<ull,max_n>,max_n> c,prefix;
static void init(){
c[0][0] = c[1][0] = c[1][1] = 1;
for(ull i {2};i<max_n;i++){
c[i][0]=1;
for(ull j{1};j<=i;j++){
c[i][j] = (c[i-1][j-1] + c[i-1][j])%k;
}
}
for(ull i = 2;i<max_n;i++){ //注意这里越界了这是个bug示例
for(ull j{1};j<=i;j++){
prefix[i][j] = prefix[i-1][j]+prefix[i][j-1]-prefix[i-1][j-1] + (c[i][j]==0?1:0);
}
prefix[i][i+1] = prefix[i][i];
}
}
#define NV(v)#v<<" : "<<(v)
template<class T>
struct ReadNumber{
ReadNumber& operator>>(T &num){
c=0,w=1,n=0;
while(!isdigit(c)){
if constexpr (!std::is_unsigned_v<T>){
if(c=='-')w=-1;
}
c=getchar();
}
while(isdigit(c)){
n=n*10+(c-'0');
c=getchar();
}
num = w*n;
return *this;
}
private:
char c;
T w,n;
};
ReadNumber<ull> readull;
int main(){
readull>>t>>k;
// std::cout<<NV(t)<<'\n'<<NV(k)<<'\n';
init();
for(ull i {0};i<t;i++){
// std::cout<<NV(t)<<'\n'<<NV(k)<<'\n';
readull>>n>>m;
// std::cout<<"test\n";
m = std::min(m,n);
std::cout<<(prefix[n][m])<<'\n';
}
}