test20181017 B君的第二题

题意

分析

考场50分

旁边的L君告诉我,求的就是非升子序列的个数,于是写了个树状数组。

但是\(\mod{2333} > 0\)还需要组合数中没有2333的倍数,所以实际上只得了\(a_i \leq 2333\)的部分分,还好。

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#define rg register
#define il inline
#define co const
#pragma GCC optimize ("O0")
using namespace std;
template<class T> il T read(T&x)
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==‘-‘)
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-‘0‘,ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXN=3e5+7,mod=1e9+7;
int n;
int a[MAXN],b[MAXN];

int rnk(int x)
{
    return lower_bound(b+1,b+n+1,x)-b;
}

int f[MAXN];

int lowbit(int x)
{
    return x&-x;
}

void add(int p,int v)
{
    for(int i=p;i<=n+1;i+=lowbit(i))
    {
        (f[i] += v) %= mod;
    }
}

int sum(int p)
{
    int res=0;
    for(int i=p;i;i-=lowbit(i))
    {
        (res += f[i]) %= mod;
    }
    return res;
}

int main()
{
  freopen("hangzhou.in","r",stdin);
  freopen("hangzhou.out","w",stdout);
    read(n);
    for(int i=1;i<=n;++i)
        b[i]=read(a[i]);
    sort(b+1,b+n+1);

    add(n+1,1);
    for(int i=1;i<=n;++i)
    {
        int p=rnk(a[i]);
        add(p,(sum(n+1) + mod - sum(p-1)) % mod);
    }
    printf("%d\n",(sum(n) + mod - n) % mod);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

标解

其实是lucas定理的运用。这跟CTSC2017吉夫特有相似之处。

由于\(a_i<233333\),所以表示成2333进制最多有2位,所以有

\[
\binom{a_i}{a_j} > 0 (\mod{2333}) \\rightarrow \binom{a_i \mod{2333}}{a_j \mod{2333}} \cdot \binom{a_i / 2333}{a_j / 2333} > 0 (\mod{2333}) \\rightarrow a_i \mod{2333} \geq a_j \mod{2333} 且 a_i / 2333 \geq a_j / 2333
\]

转化成二维点的右上角矩阵内的方案数查询,用二维树状数组维护。

时间复杂度\(O(n \log^2 p)\)

代码实现的时候为了适应树状数组查询左下角,将下标取成相反数+p。

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#define rg register
#define il inline
#define co const
#pragma GCC optimize ("O0")
using namespace std;
template<class T> il T read(T&x)
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==‘-‘)
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-‘0‘,ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int mod=1e9+7,p=2333;

int c[p+7][p+7];

int lowbit(int x)
{
    return x&-x;
}

void add(int x,int y,int v)
{
    for(int i=x;i<=p;i+=lowbit(i))
        for(int j=y;j<=p;j+=lowbit(j))
            (c[i][j] += v) %= mod;
}

int sum(int x,int y)
{
    int res=0;
    for(int i=x;i;i-=lowbit(i))
        for(int j=y;j;j-=lowbit(j))
            (res += c[i][j]) %= mod;
    return res;
}

int main()
{
  freopen("hangzhou.in","r",stdin);
  freopen("hangzhou.out","w",stdout);
    int n;
    read(n);
    int ans=0;
    while(n--)
    {
        int x,y;
        read(x);
        y = p - x % p;
        x = p - x / p;
        int t = sum(x,y);
        (ans += t) %= mod;
        add(x,y,t + 1);
    }
    printf("%d\n",ans);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

原文地址:https://www.cnblogs.com/autoint/p/9804755.html

时间: 2024-10-12 16:11:06

test20181017 B君的第二题的相关文章

2016/1/12 第一题 输出 i 出现次数 第二题 用for循环和if条件句去除字符串中空格 第三题不用endwith 实现尾端字符查询

1 import java.util.Scanner; 2 3 4 public class Number { 5 6 private static Object i; 7 8 /* 9 *第一题 mingrikejijavabu中字符“i” 出现了几次,并将结果输出*/ 10 public static void main(String[] args) { 11 12 String r ="imingrikejijavabi"; 13 14 15 //第一种 截取 16 int a=

最后一周第二天训练赛之第二题

试题: B - B Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice SPOJ ICODER Description Mathews uses a brand new 16-bit instruction processor. (Yeah i am being sarcastic!). It has one register (say R) and it su

Learning Perl 第九章习题第二题

把输入文件中的所有Fred换成Larry, 不区分大小写. 知识点 1. 文本文件读写 2. 简单的正则替换 3. unless 的用法 4. $_ 的用法 Learning Perl 第九章习题第二题,布布扣,bubuko.com

2014百度之星资格赛第二题

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2560    Accepted Submission(s): 366 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.

NOIP2005-普及组复赛-第二题-校门外的树

题目描述 Description 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种有一棵树. 由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示.已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些区域中的树(包括区域端点处的两棵树)移走.你的任务是计算将这些树都移走后,马路上还有多少棵树. 输入输出

第二题、第三题、第四题

1.以编程方式操作 HttpCachePolicy 类. HttpCachePolicy.SetExpires HttpCachePolicy.SetCacheability |NoCache|Private|Public|Server|ServerAndNoCache |ServerAndPrivate 2<%@ OutputCache Duration="60" VaryByParam="None" %>Duration 和 VaryByParam

05:统计单词数【NOIP2011复赛普及组第二题】

05:统计单词数 总时间限制:  1000ms 内存限制:  65536kB 描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置.注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样

LeetCode 第二题,Median of Two Sorted Arrays

题目再现 There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 题意解析 题目意思是给两个大小为m,n的有序数组(m,n可能为0),要求找出这两个数组的中位数.并且程序的时间复杂度必须不能超过O(log(m+n)). 这道题的

“金山杯2007逆向分析挑战赛”第一阶段第二题

注:题目来自于以下链接地址: http://www.pediy.com/kssd/ 目录:第13篇 论坛活动 \ 金山杯2007逆向分析挑战赛 \ 第一阶段 \ 第二题 \ 题目 \ [第一阶段 第二题] 题目描述: 己知是一个 PE 格式 EXE 文件,其三个(section)区块的数据文件依次如下:(详见附件)  _text,_rdata,_data 1. 将 _text, _rdata, _data合并成一个 EXE 文件,重建一个 PE 头,一些关键参数,如 EntryPoint,Imp