lightoj 1085



题意:求有多少子序列满足

 i1 < i2 < i3 < ... < ik 且  Ai1 < Ai2 < Ai3 < ... < Aik

code:

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define pi acos(-1.0)
#define maxn (100000 + 50)
#define mod 1000000007
#define Lowbit(x) (x & (-x))
using namespace std;
typedef long long int LLI;

int a[maxn];
int acopy[maxn];
int c[maxn];

void Add(int x,int add,int n) {
    while(x <= n) {
        c[x] = (c[x] + add) % mod;
        x = x + Lowbit(x);
    }
}

int Sum(int n) {
    int sum = 0;
    while(n > 0) {
        sum = (sum + c[n]) % mod;
        n = n - Lowbit(n);
    }
    return sum % mod;
}

int main() {
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    int t,n;
    scanf("%d",&t);
    for(int Case = 1; Case <= t; Case ++) {
        scanf("%d",&n);
        int cnt = 1;
        memset(c,0,sizeof(c));
        for(int i = 1; i <= n; i ++)  {
            scanf("%d",&a[i]);
            acopy[i] = a[i];
        }
        sort(acopy + 1,acopy + n + 1);
        int n2 = unique(acopy + 1,acopy + n + 1) - acopy;//unique删除重复元素(实际上是把重复的元素都挪到数组后面,返回不重复数组最后一个元素的下标 + 1)
        for(int i = 1; i <= n; i ++) {
            int pos = lower_bound(acopy + 1,acopy + n2,a[i]) - acopy;//离散化
            Add(pos,Sum(pos - 1) + 1,n2 - 1);
        }
        printf("Case %d: %d\n",Case,Sum(n2 - 1));//减1是因为访问不到n2的位置
    }
    return 0;
}
/*
c[i]表示以第i个元素a[i]结尾的符合条件的子序列有c[i]个,假设上一个比a[i]小的元素下标为k,显然c[i]等于c[k] + 1;
那么离散化之后a[i]在这个数组中的位置是pos,那么上一个比它小的元素的下标一定是 pos - 1
其实相当于一个一个的把a[i]放进序列
附数据(input):
10
2
7 -7
3
16 4 -10
12
-14 3 5 16 8 -11 7 0 5 8 8 -8
12
15 3 -6 -13 1 -9 6 15 -9 14 16 13
6
-14 12 10 -8 8 11
10
-4 10 1 0 0 16 -11 -9 7 -4
2
5 14
以及离散化后a[i]的坐标以及a[i] 的值:
Case 1:
pos =   2   a[i] =   7
pos =   1   a[i] =  -7
Case 2:
pos =   3   a[i] =  16
pos =   2   a[i] =   4
pos =   1   a[i] = -10
Case 3:
pos =   1   a[i] = -14
pos =   5   a[i] =   3
pos =   6   a[i] =   5
pos =  12   a[i] =  16
pos =   8   a[i] =   8
pos =   2   a[i] = -11
pos =   7   a[i] =   7
pos =   4   a[i] =   0
pos =   6   a[i] =   5
pos =   8   a[i] =   8
pos =   8   a[i] =   8
pos =   3   a[i] =  -8
Case 4:
pos =   9   a[i] =  15
pos =   5   a[i] =   3
pos =   3   a[i] =  -6
pos =   1   a[i] = -13
pos =   4   a[i] =   1
pos =   2   a[i] =  -9
pos =   6   a[i] =   6
pos =   9   a[i] =  15
pos =   2   a[i] =  -9
pos =   8   a[i] =  14
pos =  10   a[i] =  16
pos =   7   a[i] =  13
Case 5:
pos =   1   a[i] = -14
pos =   6   a[i] =  12
pos =   4   a[i] =  10
pos =   2   a[i] =  -8
pos =   3   a[i] =   8
pos =   5   a[i] =  11
Case 6:
pos =   3   a[i] =  -4
pos =   7   a[i] =  10
pos =   5   a[i] =   1
pos =   4   a[i] =   0
pos =   4   a[i] =   0
pos =  10   a[i] =  16
pos =   1   a[i] = -11
pos =   2   a[i] =  -9
pos =   6   a[i] =   7
pos =   3   a[i] =  -4
Case 7:
pos =   1   a[i] =   5
pos =   2   a[i] =  14
Case 8:
pos =   1   a[i] =   5
pos =   2   a[i] =  14
Case 9:
pos =   1   a[i] =   5
pos =   2   a[i] =  14
Case 10:
pos =   1   a[i] =   5
pos =   2   a[i] =  14
运行结果(output):
Case 1: 2
Case 2: 3
Case 3: 121
Case 4: 137
Case 5: 21
Case 6: 37
Case 7: 3
Case 8: 3
Case 9: 3
Case 10: 3
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sigma函数是指一个数字的所有因子之和。给定一个数字n,需要求出有多少个数字的Sigma函数是偶数。\[2\] 为了解决这个问题,可以先筛选出n范围内的素数(范围在10^6即可),然后对n进行素因子分解。对于每个因子,如果它的Sigma函数中连乘的每一项都是偶数,那么整个Sigma函数就是偶数。具体实现中,可以判断每个因子的平方根是否为偶数,如果是偶数,则减去(平方根+1)/2。\[1\] 另外,还可以使用O(1)的做法来解决这个问题。根据观察,所有的完全平方数及其两倍的值都会导致Sigma函数为偶数。因此,可以直接计算n的平方根,然后减去(平方根+1)/2即可得到结果。\[3\] #### 引用[.reference_title] - *1* [Sigma Function](https://blog.csdn.net/PNAN222/article/details/50938232)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【LightOJ1336】Sigma Function(数论)](https://blog.csdn.net/qq_30974369/article/details/79009498)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值