hdu 5230 ZCC loves hacking(BestCoder Round #41)

ZCC loves hacking

                                                  Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)

Total Submission(s): 126    Accepted Submission(s): 49

Problem Description

Now, a Codefires round is coming to end. ZCC has got C(0≤C≤106) points
by solving all problems. He is amazed that all other contestants in his room have also solved the hardest problem. So he concludes that most contestants are gonna get FST after the contest except the top rated coder Memset137. Before that, ZCC will hack them
to make his score higher. There are N(1≤N≤100000) other
contestants in ZCC‘s room. They are sorted by their ratings(So Memset137 is the N-th contestant). When ZCC successfully hacks the i-th contestant, he will get i points. You may assume ZCC can hack every wrong solution in very little time, and Memset137 is
the contestant with number N. During that time, other contestants won‘t bother him.

Since ZCC is a modest winner, he doesn‘t want his score to be too high. ZCC wonders how many ways are there that he can choose some contestants‘ solutions except the one submitted by Memset137 and hack them so that his final score is between L and R(C≤L≤R<C+N).

Obviously the result can be very large, so please output it modulo 998244353.

Input

The first line contains an integer T(T=100) which
denotes the number of test cases.

For each test case, there will be four integers N(N≤105), C, L, R in
a single line.

For 95% of the test cases, N≤2000.

For 97% of the test cases, N≤50000.

Output

For each test case, print a single integer which is the answer.

Sample Input

3
3 0 1 2
5 13 14 17
100 0 23 59

Sample Output

2
6
90567

官方题解

因为第N个人的作用仅仅是丰富题面,可以直接把N减1。C的作用仅仅是为了使情景更逼真,可以直接把L和R减去C。
显然选的人的个数最多是O(n??√)的。
题目中有个条件,保证了想要选的数的总和不会超过N。考虑类似于背包的dp。令dp[i][j]表示现在已经选了最大的i个想选的数,和为j时的方案数。转移的时候,要么把之前选择的每一个数增加一,要么在把之前选择的每一个数都增加一个基础上,再新加入一个当前大小为1的数。
若最后选的个数为i,那么就对答案产生∑Rj=Ldp[i][j]的贡献。累加即可。注意一个都不选也是合法的。
复杂度O(nn??√).
PS:解释下转移方程,由于选的值是不能重复,直接用背包肯定超时,这里就用了一个巧妙的方法,移位,将i
   个数右移1位,即每个数都增加1,即是dp[i][j+i],右移一位后最前面会空出1位,这时在最前面增加一个数
    1,因为经过移位,所有的数都比1大,所以不会出现重复,即dp[i+1][j+i+1].
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=100000+100;
const int mod= 998244353;
const int maxm=450;
int dp[2][maxn+5];
int s[maxn+5];
int main()
{
    int t,n;
    dp[1][1]=1;
    int it=1;//滚动数组标记
    for(int i=1; i<=maxm; i++,it=!it)
    {
        for(int j=1; j<=maxn; j++)
        {
            if(j+i<=maxn)
                dp[it][j+i]=(dp[it][j+i]+dp[it][j])%mod;
            if(j+i+1<=maxn)
                dp[!it][j+i+1]=(dp[it][j]+dp[!it][j+i+1])%mod;
            s[j]=(s[j]+dp[it][j])%mod;//取的值为j的和
            dp[it][j]=0;//为下一行初始化
        }
    }
    for (int j = 1; j < maxn; j++)//前缀和
    s[j] = (s[j] + s[j - 1]) % mod;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int c,l,r;
        scanf("%d%d%d",&c,&l,&r);
        r=r-c;
        l=l-c;
        int ans=s[r];
        if(l>0)
        ans=(ans-s[l-1]+mod)%mod;
        if(l==0)//全部不取时
        ans++;
        printf("%d\n",ans);
    }
    return 0;
}

时间: 2024-10-27 04:34:42

hdu 5230 ZCC loves hacking(BestCoder Round #41)的相关文章

HDU 5268 ZYB loves Score (BestCoder Round#44)

题目链接:ZYB loves Score 题面: ZYB loves Score Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 395    Accepted Submission(s): 232 Problem Description One day,ZYB participated in the BestCoder Contest

HDU 5995 Kblack loves flag ---BestCoder Round #90

题目链接 用两个布尔数组分别维护每个行/列是否被插过旗帜,最后枚举每一行.列统计答案即可.空间复杂度O(n+m),时间复杂度O(n+m+k). #include <cstdio> #include <iostream> #include <cstring> using namespace std; int t,ansx[1000005],ansy[1000005],ax,ay; const int _K=50268147,_B=6082187,_P=100000007;

HDU 5996 dingyeye loves stone ---BestCoder Round #90

题目链接 设根节点的深度为0,将所有深度为奇数的节点的石子数目xor起来,则先手必胜当且仅当这个xor和不为0. 证明同阶梯博弈.对于偶深度的点上的石子,若对手移动它们,则可模仿操作:对于奇深度上的石子,移动一次即进入偶深度的点. 时空复杂度O(n). 用vector存搜一下就行. #include <cstdio> #include <iostream> #include <vector> #include <cstring> using namespac

HDU 5228 ZCC loves straight flush( BestCoder Round #41)

题目链接:pid=5228">ZCC loves straight flush pid=5228">题面: pid=5228"> ZCC loves straight flush Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 827    Accepted Submission(s): 340

暴力 BestCoder Round #41 1001 ZCC loves straight flush

题目传送门 1 /* 2 m数组记录出现的花色和数值,按照数值每5个搜索,看看有几个已满足,剩下 5 - cnt需要替换 3 ╰· 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <iostream> 8 #include <cstring> 9 #include <string> 10 using namespace std; 11 12 const int MAXN = 1

BestCoder Round #41 -- (A,B)

题目传送:BestCoder Round #41 A.ZCC loves straight flush 思路:简单题,不过刚开始没看清题,wa了好几次,然后才发现输入不连续也可以,就是说每个同一花色的牌都可以放在一块,不用在意输入顺序,感觉这里题目应该说清楚点好些 AC代码(略挫,比赛时写的都比较乱): #include <cstdio> #include <cstring> #include <iostream> #include <algorithm>

hdu 4882 ZCC Loves Codefires(数学题+贪心)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4882 ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

JAVA hdu 4882 ZCC Loves Codefires

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4882 题解:参考题后Discuss javaherongwei 的讲解 考察序列中相邻的两题i, j(i在前).交换它们后,解出它们之前的题目所带来的时间对答案的贡献是不变的,它们对它们后面的题目的贡献也是不变的,其他题目之间对答案的贡献自然也是不变的.唯一的变化就是,原来的EiKj一项变成了EjKi一项.那么,为了使答案变优,需要满足的条件是EjKi≤EiKj.也即Ei/Ki≥Ej/Kj.那么,最

hdu 4882 ZCC Loves Codefires (贪心 推导)

题目链接 做题的时候凑的规律,其实可以 用式子推一下的. 题意:n对数,每对数有e,k, 按照题目的要求(可以看下面的Hint就明白了)求最小的值. 分析:假设现在总的是sum, 有两个e1 k1 e2 k2 则先选e1 为 (sum+e1)*k1+(sum+e1+e2)*k2 先e2: (sum+e2)*k2 + (sum+e1+e2)*k1. 比较两个式子发现不同的部分分别是 e1*k2   e2*k1; 比较大小移向 e1/k1  e2/k2, 那个小,就选那个,能达到最小. 官方题解: