• [Ynoi2011]初始化


    题目传送门

    题意

    • 给定一个序列,支持区间求和和跳点加(即对于 (y+kx(k in N)) 位置上加)

    Sol

    第一道完全没有提示做出的 Ynoi。

    考虑到题目和 P3396 哈希冲突 有点像,不如先看一下那一题题解吧。

    获得灵感了吗?

    对于修改操作,我们仍然分两类。

    1. (x < sqrt n)

    同样考虑记录 (f_{i}{j}) 表示 (x=i)(y=j) 的修改总和。

    我们考虑统计答案。

    答案即为 (sumlimits_{i=l}^r a_i+sumlimits_{i=1}^{sqrt n}sumlimits_{j=1}^i (f_{i,j} imes(leftlceil dfrac{r-j}{i} ight ceil-leftlceil dfrac{l-1-j}{i} ight ceil)))

    显然可以分开算后用前缀和优化掉一个 (sqrt n)

    (s_{i,j}) 表示 (f_{i,j})(j) 一维取前缀和,即 (s_{i,j}=sumlimits_{k=1}^j f_{i,k})

    答案即可表示为 (sumlimits_{i=l}^r a_i+sumlimits_{i=1}^{sqrt n}((s_{i,i} imes(leftlfloor dfrac{r}{i} ight floor-leftlfloor dfrac{l-1}{i} ight floor))+s_{i,r\%i}-s_{i,(l-1)\%r}))

    事实上这个意义比上式更好理解。(

    修改处理 (s_{i,j}) 即可。

    1. (x ge sqrt n)

    暴力修改即可

    如上式,考虑迅速求 (sumlimits_{i=l}^r a_i),那么考虑分块。

    总复杂度 (O((n+m)sqrt n))

    记得开 ( ext{long long})

    ( ext{Code})

    // wish to get better qwq
    
    #include<bits/stdc++.h>
    #define re register int
    #define pb push_back
    
    using namespace std;
    typedef long long ll;
    
    template <typename T> void rd(T &x){
    	ll fl=1;x=0;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') fl=-fl;
    	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    	x*=fl;
    }
    void wr(ll x){
    	if(x<0) x=-x,putchar('-');
    	if(x<10) putchar(x+'0');
    	if(x>9) wr(x/10),putchar(x%10+'0');
    }
    
    // ---------- IO ---------- //
    
    const int N=2e5+5,SQ=505,mod=1e9+7;
    int n,m,op,l,r,qaq,len,tot;
    ll a[N],sum[SQ],s[SQ][SQ];
    // s[i][j] 指 x=i [1,j] 中 add 的值 
    
    inline int block(int x){return (x-1)/len+1;}
    inline int L(int x){return (x-1)*len+1;}
    inline int R(int x){return x*len;}
    
    inline void modify(int x,int y,int z){
    	if(x>=tot){
    		for(re i=y;i<=n;i+=x) a[i]+=z,sum[block(i)]+=z;
    		return ;
    	}
    	for(re i=y;i<=x;i++) s[x][i]+=z;
    //	cout<<x<<' '<<y<<' '<<z<<endl;
    //	for(re i=0;i<=x;i++) cout<<s[x][i]<<' ';cout<<endl;
    	return ;
    }
    
    inline ll query(int l,int r){
    	ll ans=0;int lb=L(block(l)+1),rb=R(block(r)-1),tmp=block(r)-1;
    	if(block(l)==block(r)){
    		for(re i=l;i<=r;i++) ans+=a[i];
    	}
    	else{
    		for(re i=l;i<lb;i++) ans+=a[i];
    		for(re i=rb+1;i<=r;i++) ans+=a[i];
    		for(re i=block(l)+1;i<=tmp;i++) ans+=sum[i];
    	}
    //	cout<<ans<<endl;
    	for(re i=1;i<=tot;i++) ans+=s[i][r%i]-s[i][(l-1)%i]+s[i][i]*(r/i-(l-1)/i);
    	return ans;
    }
    
    // ---------- Sqrt & Operations ---------- //
    
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	rd(n);rd(m);len=(int)sqrt(n);tot=block(n);
    	for(re i=1;i<=n;i++) rd(a[i]),sum[block(i)]+=a[i];
    	for(re i=1;i<=m;i++){
    		rd(op);rd(l);rd(r);
    		if(op==1) rd(qaq),modify(l,r,qaq);
    		else wr(query(l,r)%mod),puts("");
    	}
    	return 0;
    }
    
    // ---------- Main ---------- //
    
    
  • 相关阅读:
    Leetcode 283. Move Zeroes
    利用脚本,一键设置java环境变量(默认安装路径)
    'wmic' 不是内部或外部命令,也不是可运行的程序 解决方法
    PowerShell因为在此系统中禁止执行脚本解决方法
    使用VBSCRIPT安装字体
    批处理基本知识以及进阶 V2.0
    Vbs 脚本编程简明教程之一
    用批处理,批量安装字体文件 (Erector.bat)
    windows 7 系统装机优化
    使用批处理替换windows系统中的hosts文件
  • 原文地址:https://www.cnblogs.com/danieljiang/p/14410767.html
Copyright © 2020-2023  润新知