标签:
给出n个数, m个操作, 每个操作有两种, 将一段区间加上某个值, 或者询问一个k, a[i] = a[j] = k, 输出满足条件的最大的j-i, 如果没有输出-1。
做法是将数组分块, 第一次做这种, 抄的codeforces上面的代码...
#include<bits/stdc++.h> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, a, n) for(int i = a; i<n; i++) #define ull unsigned long long typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; multiset <int> s[1000]; const int maxn = 5e5+5; int a[maxn], N, add[1005], n; void modify(int l, int r, int val) { for(int i = l; i<=r; i++) { if(i%N==0&&i+N-1<=r) { add[i/N] += val; if(add[i/N]>1e9) add[i/N] = 1e9+1; i+=N-1; } else { s[i/N].erase(s[i/N].find(a[i])); a[i]+=val; if(a[i]>1e9) a[i] = 1e9+1; s[i/N].insert(a[i]); } } } int query(int x) { int l = -1, r = -2; for(int i = 0; i<n; i++) { if(a[i] + add[i/N] == x) { l = i; break; } if(i%N==0&&i+N-1<n) { if(s[i/N].find(x-add[i/N])==s[i/N].end()) i+=N-1; } } for(int i = n-1; i>=0; i--) { if(a[i] + add[i/N] == x) { r = i; break; } if((1+i)%N == 0) { if(s[i/N].find(x-add[i/N]) == s[i/N].end()) i = i-N+1; } } return r-l; } int main() { int m, cnt = 0; cin>>n>>m; N = sqrt(n*1.0); for(int i = 0; i<n; i++) { scanf("%d", &a[i]); if(i&&i%N==0) cnt++; s[cnt].insert(a[i]); } while(m--) { int sign, l, r, val; scanf("%d", &sign); if(sign == 1) { scanf("%d%d%d", &l, &r, &val); l--, r--; modify(l, r, val); } else { scanf("%d", &val); cout<<query(val)<<endl; } } return 0; }
codeforces 551E. GukiZ and GukiZiana 分块
标签:
原文地址:http://www.cnblogs.com/yohaha/p/5071329.html