發表文章

目前顯示的是有「分塊」標籤的文章

[TIOJ] 1726. Dice Wars

題目連結: http://tioj.infor.org/problems/1726 為什麼$O((N+Q)\sqrt{N})$跑得比$O((N+Q)\sqrt{N}log(N))$還要慢啊,我居然是倒數的,明明上面的人複雜度都慘的(? 總之我的想法是分塊,然後對每塊都用$O(N^2)$的方式算完每塊內的答案,接著如果答案是跨多個塊的話,則我們只要掃過每一塊,並記錄當前遇到最後面的a跟b出現在哪,然後再看看現在看到這塊的a跟b最前面出現在哪就好,完成後更新a,b的最後位置,再去檢查下一塊。 易知當塊大小為k時,複雜度為$O(Nk+\frac{NQ}{k})$故取$k=\sqrt{N}$時最佳。 #include <iostream> #include <vector> #include <utility> #include <unordered_map> using namespace std; const int N = 60025 + 5; const int SQRT_N = 245; const int INF = 1<<30; vector<pair<int,int>> que; unordered_map<int,int> ans[N], fi[SQRT_N], se[SQRT_N]; int arr[N]; int main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin >> n >> q; for(int i=0;i<n;i++) cin >> arr[i]; n = (n+SQRT_N-1)/SQRT_N*SQRT_N; for(int i=0;i<q;i++){ int x, y; cin >> x >> y; if(x > y) swap(x,y)...

[Codeforces] 551E. GukiZ and GukiZiana

題目連結: http://codeforces.com/problemset/problem/551/E 把序列分成$\sqrt{N}$塊後,每次操作就變得很簡單了,修改時如果那塊完整被覆蓋就直接在懶標記上修改,而如果沒有就把那塊重新建置一次;詢問時就先看一下懶標記,再查詢即可。複雜度$O(Q \sqrt{N})$ #include <bits/stdc++.h> using namespace std; typedef pair<int,int> PII; #define FF first #define SS second typedef long long lld; const int K = 710; const int N = 500000 + 5; lld arr[N], flag[K]; unordered_map<lld, PII> blk[K]; int main(){ ios_base::sync_with_stdio(0);cin.tie(0); int n, q; cin>>n>>q; for(int i=0;i<n;i++) cin>>arr[i]; const int k = ceil(sqrt(n)); for(int i=0;i<n;i+=k){ for(int j=i;j<min(n, i+k);j++){ if(blk[i/k].find(arr[j])==blk[i/k].end()) blk[i/k][arr[j]].FF = j; blk[i/k][arr[j]].SS = j; } } while(q--){ int tp; cin>>tp; if(tp==1){ int l, r; lld v; cin>>l...