列表

详情


NC25880. FTOS的测试

描述

长歌当哭,为君仗剑弑天下!
                                           ——李白-凤求凰





测试完毕,总得分0,系统未知错误.

在寒假将要结束时,小T与小s一起发明了一个操作系统简称FTOS),但是这个操作系统有一些漏洞,但小s没有发现,从而导致系统的崩溃,为了避免此类情况的再次发生,小T要通过一种叫随机开方的方法进行测试。

随机开方的操作流程如下:

No.1 读入一个序列a,由系统生成q组询问.

No.2 系统在这个序列中对一个随机的位置进行开方(下取整)(每次流程结束后恢复到原序列状态)。

No.3 系统生成一个区间[l,r]以及这个区间的和k,由操作系统的CPU回答:如果可以判定这个被开方数的值,回答"pass",如果有多个解输出"INF",如果无解输出"Error"。


现在小T拿到了系统的问题,现在他想知道正确的答案,以便修理FTOS。

注:本系列题不按难度排序哦

输入描述

第一行两个整数n,q

第二行n个数代表a

后q行每行三个整数l,r,k

输出描述

共q行表示FTOS的回答。

示例1

输入:

3 2
2 2 3
1 2 2
2 3 2

输出:

Error
Error

说明:

100\%\ 1≤n,q≤10^5\ 1≤a_i≤10^4


数据的提示

数据保证纯随机,且l≤r≤n,k≤a_i

但这不意味着输出“Error”可以拿满分。

题面的提示

这里的值不同指的是:即使不能确定被开方数的位置,但是能确定他们的值,且这个值唯一,输出的是"pass"而不是"INF"。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 295ms, 内存消耗: 44144K, 提交时间: 2019-07-16 10:49:21

#include<bits/stdc++.h>
#define int long long
using namespace std;
int block,sum,Ans[5000005],p[5000005],n,m,Add[5000005],q;
int a[5000005],tlps[5000005],asqrt[5000005],dif[500005],d[10005];
int PKR[500005];
inline void work(int as,int bs,int x) {
    sort(asqrt + as,asqrt + bs + 1);
    sort(PKR + as,PKR + bs + 1);
    int st = 0;
    memset(d,0,sizeof(d));
    for (int i = as; i <= bs; i++) {
        st += a[i];
        if (!d[a[i]]) {
            d[a[i]]++;
            dif[x]++;
        }
    }
    Ans[x] = st;
}
signed main() {
    //freopen("dd5.in","r",stdin);
    //freopen("dd5.out","w",stdout);
    memset(Add,0,sizeof(Add));
    scanf("%lld%lld",&n,&q);
    block = (int)sqrt(n);
    sum = n / block; 
    if (n % block) sum++;
    for (int i = 1; i <= n; i++) {
        scanf("%lld",&a[i]);
        p[i] = (i - 1) / block + 1;
        asqrt[i] = a[i] - (int)sqrt(a[i]);
        PKR[i] = a[i];
        tlps[i] = asqrt[i];
    }
    for (int i = 1; i <= sum; i++)
        work((i - 1) * block + 1,min(i * block,n),i);
    for (int i = 1; i <= q; i++) {
        int x,y,op,k,st = 0;
        scanf("%lld%lld%lld",&x,&y,&k);
        for (int j = x; j <= min(p[x] * block,y); j++)
            st += a[j];
        if (p[x] != p[y])
            for (int j = (p[y] - 1) * block + 1; j <= y; j++)
                st += a[j];
        for (int j = p[x] + 1; j <= p[y] - 1; j++)
            st += Ans[j];
        int del = st - k;
        int v = 0;
        for (int j = x; j <= min(p[x] * block,y); j++)
            if (tlps[j] == del)
                v++;
        if (p[x] != p[y])
            for (int j = (p[y] - 1) * block + 1; j <= y; j++)
                if (tlps[j] == del)
                    v++;
        for (int j = p[x] + 1; j <= p[y] - 1; j++) {
            int low = lower_bound(asqrt + (j - 1) * block + 1,min(asqrt + n,asqrt + j * block + 1),del) - (asqrt + (j - 1) * block + 1);
            int upp = upper_bound(asqrt + (j - 1) * block + 1,min(asqrt + n,asqrt + j * block + 1),del) - (asqrt + (j - 1) * block + 1);            
            if (asqrt[low] == del && low - upp - 1 >= 0)
                v += low - upp - 1;else
            if (low >= upp)
              v += low - upp;
        }
        if (v <= 0)
            printf("Error\n");
        else {
            int diff = 0;
            memset(d,0,sizeof(d));
            for (int j = x; j <= min(p[x] * block,y); j++) {
                if (!d[a[j]] && tlps[j] == del) {
                    diff++;
                    d[a[j]]++;
                }
            }
            if (p[x] != p[y])
                for (int j = (p[y] - 1) * block + 1; j <= y; j++)
                    if (!d[a[j]] && tlps[j] == del) {
                        diff++;
                        d[a[j]]++;
                    }
            for (int j = p[x] + 1; j <= p[y] - 1; j++)
            {
                int upp = upper_bound(asqrt + (j - 1) * block + 1,min(asqrt + n,asqrt + j * block + 1),del) - (asqrt + (j - 1) * block + 1);            
                int low = lower_bound(asqrt + (j - 1) * block + 1,min(asqrt + n,asqrt + j * block + 1),del) - (asqrt + (j - 1) * block + 1);
                if (PKR[upp] != PKR[low] && upp != 0 && low != 0)
                  diff += 2;
            }
            if (diff <= 1)
                printf("pass\n");
            else
            if (diff > 1)
                printf("INF\n");
        }
    }
    return 0;
}

上一题