国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[SD2014集訓]查詢(分塊+數學相關)

2019-11-14 10:42:34
字體:
來源:轉載
供稿:網友

題目描述

這里寫圖片描述 這里寫圖片描述 這里寫圖片描述 這里寫圖片描述

題解

看模數那么奇怪找一下規律看看有沒有奇怪的性質 發現每一個數立方48次后回到原數 線段樹不如分塊好寫 維護每個數立方k次后得到的數,每一個塊所有的數分別立方k次后的和 修改時,對于整塊記錄立方的次數,其余的暴力重構 重構即把塊內的點維護的立方旋轉t次,然后重新計算和 查詢時,整塊直接查詢,其余暴力 時間復雜度O(m(block+n?szblock)),可以發現當block=n?sz?????√時有最小值,O(mn?sz?????√)≈2.19s

代碼

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define LL long long#define Mod 329701061#define sz 48#define N 100005char opt;int n,m,x,y,block,tot;int t[N],num[N],l[N],r[N];LL a[N],cub[N][sz],Cub[N][sz],s[sz];void init(){ for (int i=1;i<=n;++i) { cub[i][0]=a[i]; for (int j=1;j<sz;++j) cub[i][j]=cub[i][j-1]*cub[i][j-1]%Mod*cub[i][j-1]%Mod; } for (int i=1;i<=tot;++i) for (int j=0;j<sz;++j) for (int k=l[i];k<=r[i];++k) { Cub[i][j]+=cub[k][j]; if (Cub[i][j]>=Mod) Cub[i][j]-=Mod; }}void move(int id,int rad){ if (!rad) return; for (int i=0;i<rad;++i) s[i]=cub[id][i]; for (int i=rad;i<sz;++i) cub[id][i-rad]=cub[id][i]; for (int i=0;i<rad;++i) cub[id][i+sz-rad]=s[i];}void calc(int id){ for (int i=0;i<sz;++i) { Cub[id][i]=0; for (int j=l[id];j<=r[id];++j) { Cub[id][i]+=cub[j][i]; if (Cub[id][i]>=Mod) Cub[id][i]-=Mod; } }}void change(int x,int y){ if (num[x]==num[y]) { for (int i=l[num[x]];i<x;++i) move(i,t[num[x]]); for (int i=y+1;i<=r[num[y]];++i) move(i,t[num[x]]); ++t[num[x]];if (t[num[x]]==sz) t[num[x]]=0; for (int i=x;i<=y;++i) move(i,t[num[x]]); t[num[x]]=0; calc(num[x]); return; } if (x==l[num[x]]) x=num[x]; else { for (int i=l[num[x]];i<x;++i) move(i,t[num[x]]); ++t[num[x]];if (t[num[x]]==sz) t[num[x]]=0; for (int i=x;i<=r[num[x]];++i) move(i,t[num[x]]); t[num[x]]=0; calc(num[x]); x=num[x]+1; } if (y==r[num[y]]) y=num[y]; else { for (int i=y+1;i<=r[num[y]];++i) move(i,t[num[y]]); ++t[num[y]];if (t[num[y]]==sz) t[num[y]]=0; for (int i=l[num[y]];i<=y;++i) move(i,t[num[y]]); t[num[y]]=0; calc(num[y]); y=num[y]-1; } for (int i=x;i<=y;++i) { ++t[i]; if (t[i]==sz) t[i]=0; }}LL query(int x,int y){ LL ans=0; if (num[x]==num[y]) { for (int i=x;i<=y;++i) { ans+=cub[i][t[num[x]]]; if (ans>=Mod) ans-=Mod; } return ans; } if (x==l[num[x]]) x=num[x]; else { for (int i=x;i<=r[num[x]];++i) { ans+=cub[i][t[num[x]]]; if (ans>=Mod) ans-=Mod; } x=num[x]+1; } if (y==r[num[y]]) y=num[y]; else { for (int i=l[num[y]];i<=y;++i) { ans+=cub[i][t[num[y]]]; if (ans>=Mod) ans-=Mod; } y=num[y]-1; } for (int i=x;i<=y;++i) { ans+=Cub[i][t[i]]; if (ans>=Mod) ans-=Mod; } return ans;}int main(){ scanf("%d",&n); for (int i=1;i<=n;++i) scanf("%I64d",&a[i]); block=n/floor(sqrt(n*sz)); if (!block) ++block; tot=(n-1)/block+1; for (int i=1;i<=n;++i) { num[i]=(i-1)/block+1; if (num[i]!=num[i-1]) r[num[i-1]]=i-1,l[num[i]]=i; } r[tot]=n; init(); scanf("%d",&m); for (int i=1;i<=m;++i) { opt=getchar(); while (opt!='C'&&opt!='Q') opt=getchar(); scanf("%d%d",&x,&y); if (x>y) swap(x,y); if (opt=='C') change(x,y); else printf("%I64d/n",query(x,y)); }}

總結

卡常數技巧 ①分塊大小nn?sz√ ②加法的取模改成加減 ③盡量不用乘法用加減


上一篇:SRM150_DIV2

下一篇:0005 控制語句

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 连江县| 渝中区| 抚远县| 皋兰县| 静海县| 商水县| 南澳县| 盐边县| 习水县| 屏边| 休宁县| 保康县| 金寨县| 贞丰县| 泰安市| 泰兴市| 巴塘县| 南澳县| 丁青县| 怀远县| 綦江县| 常熟市| 黑水县| 织金县| 乐昌市| 玛多县| 蛟河市| 长葛市| 武陟县| 浮梁县| 永修县| 岫岩| 金沙县| 淮安市| 绥江县| 辛集市| 司法| 长治市| 桦甸市| 贡山| 邛崃市|