【NOIP模拟赛】数列

数列


  • Description

Czy手上有一个长度为n的数列,第i个数为xi。
他现在想知道,对于给定的a,b,c,他要找到一个i,使得a * (i+1) * xi^2+(b+1) * i * xi+(c+i)=0成立。(“ * ”号为乘号)
如果有多个i满足,Czy想要最小的那个i。
Czy有很多很多组询问需要你回答,多到他自己也不确定有多少组。所以在输入数据中a=b=c=0标志着Czy的提问的结束。
更加糟糕的是,Czy为了加大难度,决定对数据进行加密以防止离线算法的出现。
假设你在输入文件中读到的三个数为a0,b0,c0,那么Czy真正要询问的a=a0+LastAns,b=b0+LastAns,c=c0+LastAns.
LastAns的值是你对Czy的前一个询问的回答。如果这是第一个询问,那么LastAns=0。所有的询问都将会按上述方式进行加密,包括标志着询问的结束的那个询问也是这样。

  • Input Format

输入文件为 seq.in
输入文件第一行包含一个整数n,表示数列的长度。
输入文件第二行包含n个整数,第i个数表示xi的值。
接下来若干行,每行三个数,表示加密后的a,b,c值(也就是上文所述的a0,b0,c0)

  • Output Format

输出文件为 seq.out
包含若干行,第i行的值是输入文件中第i个询问的答案。注意,你不需要对标志着询问结束的那个询问作答。
同时,标志着询问结束的询问一定是输入文件的最后一行。也就是,输入文件不会有多余的内容。

  • Sample Input

5
-2 3 1 -5 2
-5 -4 145
-1 -6 -509
-9 -14 40
-3 -13 21
-3 -3 -3

  • Sample Output

5
4
3
3

  • Hint

对于40%的数据,满足N<=1000,需要作出回答的询问个数不超过1000.
对于100%的数据,满足N<=50000,需要作出回答的询问个数不超过500000,xi的绝对值不超过30000,解密后的a的绝对值不超过50000,解密后的b的绝对值不超过10^8,解密后的c的绝对值不超过10^18.


  • 分析

虽然题目说防止离线算法,可这题就是离线计算啊?!
每次通过当前的答案推出上一次的答案,详见代码。


#include <queue>
#include <stack>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long n,m,x[500005],a[500005],b[500005],c[500005],ans[500005];
int main(){
    freopen("seq.in","r",stdin);
    freopen("seq.out","w",stdout);
    scanf("%lld",&n);
    for (int i=1;i<=n;i++) scanf("%lld",&x[i]);
    for (m++;~scanf("%lld%lld%lld",&a[m],&b[m],&c[m]);m++);
    ans[m-2]=-a[--m];
    for (int i=m-1;i;i--){
        if (i==371614){
            int tag=0;
        }
        long long X=-(a[i]*x[ans[i]]*x[ans[i]]*(ans[i]+1)+(b[i]+1)*x[ans[i]]*ans[i]+c[i]+ans[i]);
        long long Y=(x[ans[i]]*x[ans[i]]*(ans[i]+1)+x[ans[i]]*ans[i]+1);
        ans[i-1]=X/Y;
    }
    for (int i=1;i<m;i++) printf("%lld\n",ans[i]);
    fclose(stdin); fclose(stdout);
    return 0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值