给出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; }
3.10 update 重新写了一发。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> 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, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<ll, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1e18; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 5e5+5; vector<pll> b[800]; ll a[maxn], c[maxn], l[800], r[800], add[800], belong[maxn]; int n, cnt, block; int ansx, ansy; void rebuild(int x) { b[x].clear(); for(int i = l[x]; i<=r[x]; i++) { b[x].pb(mk(a[i], i)); } sort(b[x].begin(), b[x].end()); } void update(int x, int y, int val) { if(belong[x] == belong[y]) { for(int i = x; i<=y; i++) { a[i]+=val; } rebuild(belong[x]); return ; } for(int i = x; i<=r[belong[x]]; i++) { a[i]+=val; } for(int i = l[belong[y]]; i<=y; i++) { a[i]+=val; } for(int i = belong[x]+1; i<belong[y]; i++) { add[i] += val; } rebuild(belong[x]); rebuild(belong[y]); } void bin(int x, ll val) { auto it = lower_bound(b[x].begin(), b[x].end(), mk(val, 0)); if(it == b[x].end()) return ; if(it->first == val) { ansx = min(ansx, it->second); } it = lower_bound(b[x].begin(), b[x].end(), mk(val+1, 0)); if(it == b[x].begin()) return ; it--; if(it -> first == val) { ansy = max(ansy, it->second); } } void query(ll val) { for(int i = 1; i<=cnt; i++) { ll tmp = val-add[i]; if(tmp<0) continue; bin(i, tmp); } } int main() { int q, x, y, z, sign; cin>>n>>q; block = sqrt(n*1.0); for(int i = 1; i<=n; i++) { scanf("%I64d", &a[i]); belong[i] = (i-1)/block+1; } if(n%block) cnt = n/block+1; else cnt = n/block; for(int i = 1; i<=cnt; i++) { l[i] = (i-1)*block+1; r[i] = i*block; } r[cnt] = n; for(int i = 1; i<=cnt; i++) rebuild(i); while(q--) { scanf("%d", &sign); if(sign == 1) { scanf("%d%d%d", &x, &y, &z); update(x, y, z); } else { scanf("%d", &x); ansx = inf, ansy = -inf; query(x); if(ansx==inf) { puts("-1"); } else { printf("%d ", ansy-ansx); } } } return 0; }