洛谷-P3396 哈希冲突 分块
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                洛谷-P3396 哈希冲突 分块
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                題目
題目鏈接
題意
給你個數列,編號為1…n1…n。 
 給出兩種操作:
- 查詢操作:查詢所有編號模xx得yy的對應數字之和。
- 修改操作:把編號為xx的數字,修改為yy。
題解
我們先從最為暴力的思路出發:
- 對于查詢xx、yy來說,我們要統計的就是編號為y,x+y,…,kx+yy,x+y,…,kx+y的數字之和。
我們可以把要求的東西簡寫成sum[x][y]sum[x][y],代表的含義是模xx余yy的編號對應的數字之和,下面我們需要來維護這個東西。 
 預處理:
預處理sum[x][y]sum[x][y]的時間復雜度為O(n2)O(n2)
想要降低時間復雜度,我們可以想到分塊,分塊能降低到O(nn ̄√)O(nn)
做法如下: 
 我們對模數進行分塊,當模數x<n ̄√x<n的時候,我們暴力與處理,時間復雜度為O(nn ̄√)O(nn)。 
 當模數x>n ̄√x>n時候我們不將其處理。
詢問模數x<n ̄√x<n時候,直接回答。 
 詢問模數x>n ̄√x>n時候,暴力按照a[y]+a[x+y]+…+a[kx+y]a[y]+a[x+y]+…+a[kx+y]進行計算,由于x>n ̄√x>n,所以求和的數不超過nn ̄√nn個。
總的復雜度是x>n ̄√x>n。
代碼
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; #define pr(x) cout<<#x<<":"<<x<<endl int n,m; int val[150007]; int dp[1007][1007]; int main(){scanf("%d %d",&n,&m);for(int i = 1;i <= n;++i){int v;scanf("%d",&v);val[i] = v;}for(int i = 1;i <= n;++i){for(int p = 1;p <= 400;++p){dp[p][i%p] += val[i];}}char op;int x,y;for(int i = 0;i < m;++i){scanf(" %c %d %d",&op,&x,&y);if(op == 'A'){if(x <= 400) printf("%d\n",dp[x][y]);else{int ans = 0;for(int j = y;j <= n;j += x){ans += val[j];}printf("%d\n",ans);}}else{for(int p = 1;p <= 400;++p){dp[p][x%p] += y - val[x];}val[x] = y;}}return 0; }總結
以上是生活随笔為你收集整理的洛谷-P3396 哈希冲突 分块的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 经典拜年词 经典拜年词有哪些
- 下一篇: 全叶马兰介绍 分布在哪里
