首页 > 其他分享 >CF-1921-F-根号分治

CF-1921-F-根号分治

时间:2024-01-24 11:15:22浏览次数:32  
标签:pre int sum CF sqrt 1921 根号

1921-F 题目大意

有一个长为\(n\)的序列\(a\),有\(q\)次询问,对于每次询问:

  • 给定\(s,d,k\),请输出\(\sum_{i=1}^{k}i*a_{s+(i-1)*d}\)

Solution

根号分治。

  • 对于\(d\ge \sqrt{n}\)的情况,直接暴力计算即可。
  • 对于\(d\le \sqrt{n}\)的情况,这时需要预处理两个数组:\(pre,sum\),这里\(pre[d][i]\)表示公差为\(d\),最后一个元素为\(a[i]\)的数列的前缀和;\(sum[d][i]\)表示公差为\(d\)的数列,\(a[i]*\)其项数的前缀和,递推式子如下:

\[pre[d][i+d]=pre[d][i]+a[i] \]

\[sum[d][i+d]=sum[d][i]+a[i]*(i/d+1) \]

这时可以\(O(1)\)的计算出询问结果为\(sum[d][s+d*k]-sum[d][s]-(pre[d][s+d*k]-pre[d][s])*(s/d)\)。

根号算法结合了暴力计算以及数列求和的优点,真正实现了时空平衡,复杂度均为\(O(n\sqrt{n})\)。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;

const int N=1e5+10;
ll pre[400][N],sum[400][N];

void solve(){
    int n,q;
    cin>>n>>q;
    int B=sqrt(n);
    vector<ll> a(n+1);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int d=1;d<=B;d++){
        for(int i=1;i<=n;i++){
            pre[d][i+d]=pre[d][i]+a[i];
            sum[d][i+d]=sum[d][i]+a[i]*(i/d+1);
        }
    }
    while(q--){
        int s,d,k;
        cin>>s>>d>>k;
        if(d<B){
            cout<<sum[d][s+d*k]-sum[d][s]-(pre[d][s+d*k]-pre[d][s])*(s/d)<<" ";
        }else{
            ll res=0;
            for(ll i=1;i<=k;i++){
                res+=a[s+d*(i-1)]*i;
            }
            cout<<res<<" ";
        }
    }
    cout<<'\n';
}

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

标签:pre,int,sum,CF,sqrt,1921,根号
From: https://www.cnblogs.com/fengxue-K/p/17984154

相关文章

  • CF-55-D-数位DP
    55-D题目大意给定区间\([l,r]\),问区间中有多少个数\(x\)满足:对于它的每一个非\(0\)位上的数\(y\),都有\(y|x\)。Solution经典的数位DP题型。记录状态:\(f[pos][num][lcm]\)表示填完前\(pos\)位上的数,这些数构成了数\(num\),各个非\(0\)位数字的最小公倍数为\(lcm\),如果数\(lcm|......
  • CF327C Magic Five 题解
    CF327CMagicFive搬运工单调队列优化DP加等比数列求和首先\(5\)的倍数要求末尾是\(0\)或\(5\)所以我们只用看给定字符串的\(0\)和\(5\)就好,我们钦定他是最终的数的末尾。在他之前的选择删掉,在他之后的全部删掉,方案数就是\(2^{pow-1}\),答案累加就可以了。容易想到......
  • CF-91-B-单调栈+二分
    91-B题目大意给定一个长为\(n\)的序列\(a\),对于每个\(a[i]\),你需要找到一个\(j\)满足\(a[i]>a[j]\)且\(j-i\)最大。Solution逆序遍历,维护一个单调递减的栈,如果当前枚举的\(a[i]\)小于栈顶元素,则入栈。如果\(a[i]\)大于栈顶元素,那么后面的元素如果大于\(a[i]\),那么也大于栈顶......
  • CF-292-D-并查集
    292-D题目大意给定一张无向图,由\(n\)个顶点\(m\)条边。有\(q\)次询问,每次询问将\([l,r]\)的边删去,问图中有多少连通分量。Solution涉及连通分量,尝试应用并查集解决。记录一个前缀并查集\(pre[i]\),表示前\(i\)条边连通后的图;和一个后缀并查集\(suf[i]\),表示后\(m-i\)条边连通......
  • CF1424M Ancient Language 题解
    1.题意描述一本字典中有\(r\)\((1\leqr\leq10^6)\)个单词,单词长度不超过$10^3$,所有字母都是小写英文字母,但字母排序不是按英文字母排序,求所有出现字母的一种排序,如果不存在,输出"IMPOSSIBLE"。2.题目分析由排序规则可知,对于字符串\(s\)和\(t\),\(s\)排在\(t\)......
  • CF618C Constellation 题解
    题意描述给定\(n\)个点(\(n\leq10^5\)),找到三个点满足这三个点不在同一直线上且三个点构成的三角形中不包含其他点,保证所有点不会在同一直线上。题目分析首先必然每一个点都可以作为一组解中的点。不妨其中一个点编号为\(1\)。找一个点作为第二个点,为了使没有点在这条边上,这......
  • CF1036F Relatively Prime Powers 题解
    题目分析对于一个不合法的数\(x(x\ge2)\),设\(x=\prodp_i^{r_i}\),令\(g=\gcd(r_1,r_2,\ldots,r_k)\),则\(x=\left(\prodp_i^{r_i/g}\right)^g\),所以\(x\)是一个正整数的\(g\)次方。所以可以枚举上文的\(g\),把每一类不合法方案排除掉,就是答案。设\(f(i)\)表示\(2\)......
  • CF1914D Three Activities
    题目大意给定三个数组\(a,b,c\)找三个互不相同的整数\(i,j,k\)使得\(a_i+b_j+c_k\)的值最大.思路首先想到的当然是枚举\(i,j,k\)然后找到最大值,但这种方法的时间复杂度是\(O(n^3)\),显然会喜提\(TLE\).当然由瞪眼法可知,因为我们只需要找到\(a_i+b_j......
  • CF-1831-E-卡特兰数+异或哈希+差分
    1831-E题目大意给定一个整数\(n\),和\(k\)个区间,区间端点范围在\([1,n]\)内。如果有一个长为\(n\)合法的括号序列,且它的这\(k\)个区间\([l,r]\)中的子括号序列也是合法的,那么称这个括号序列是“好的”。请你求出有多少个长度为\(n\)的“好的”括号序列,答案对\(998244353\)取模......
  • 从CF1875C学习lowbit运算判断是否为 2 的 k 次幂
    Problem-1875C-Codeforces本题判断无解的时候要判断该数是否为2的k次幂,我的做法是预处理出2的次幂数表。看题解发现可以用lowbit操作。lowbit操作intlowbit(intx){returnx&(-x);}根据补码原理,该操作可以求出来X最靠右的\(1\)构成的数。判断\(x\)......