标签:using mes 最大的 span main upd c++ 从右到左 std
题意:有2个操作,1 l, r, c 将区间[ l,r ]里的值都加上c, 2 y 需要找到最大的 j - i 需要满足 xj = xi = y。
题解:暴力分块,开sqrt(n)块,然后每次更新的时候,如果这个块被全覆盖,就用lazy标记,然后零散的点就直接更新,再暴力重建。然后对于每一次询问,都查询y-lazy值看看他有没有,从左到右先早到最小的点,然后break, 再从右到左找到最大的点,再break掉。最终返回就是答案了。
注意就是CF数据有点毒瘤,开int之后,他会数据溢出,然后还刚好有一个地方会访问到,随意最后还是开了LL,时间上慢了一点。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 4 #define LL long long 5 #define ULL unsigned LL 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define lson l,m,rt<<1 10 #define rson m+1,r,rt<<1|1 11 #define max3(a,b,c) max(a,max(b,c)) 12 #define min3(a,b,c) min(a,min(b,c)) 13 #define _S(X) cout << x << ‘ ‘; 14 #define __S(x) cout << x << endl; 15 typedef pair<int,int> pll; 16 const int INF = 0x3f3f3f3f; 17 const LL mod = (int)1e9+7; 18 const int N = 5e5 + 100; 19 int l[N], r[N], belong[N]; 20 LL a[N], lazy[N]; 21 int n, m, tot; 22 vector<LL> vc[N]; 23 void Build(){ 24 m = sqrt(n); 25 tot = n/m; 26 if(n%m) tot++; 27 for(int i = 1; i <= n; i++){ 28 belong[i] = (i-1)/m + 1; 29 vc[(i-1)/m + 1].pb(a[i]); 30 } 31 for(int i = 1; i <= tot; i++){ 32 l[i] = (i-1)*m + 1; 33 r[i] = i*m; 34 sort(vc[i].begin(), vc[i].end()); 35 } 36 r[tot] = n; 37 } 38 void PushDown(int rt){ 39 vc[rt].clear(); 40 for(int i = l[rt]; i <= r[rt]; i++) 41 vc[rt].pb(a[i]); 42 sort(vc[rt].begin(), vc[rt].end()); 43 } 44 void Update(int x, int y, int c){ 45 int idx = belong[x], idy = belong[y]; 46 if(idx == idy){ 47 for(int i = x; i <= y; i++) 48 a[i] += c; 49 PushDown(idx); 50 } 51 else { 52 for(int i = x; i <= r[idx]; i++) 53 a[i] += c; 54 for(int i = l[idy]; i <= y; i++) 55 a[i] += c; 56 PushDown(idx); PushDown(idy); 57 for(int i = idx+1; i < idy; i++) 58 lazy[i] += c; 59 } 60 } 61 int Query(int y){ 62 int ll = 0, rr = 0; 63 for(int i = 1; i <= tot; i++){ 64 int t = *lower_bound(vc[i].begin(), vc[i].end(), y-lazy[i]); 65 if(y - lazy[i] == t){ 66 for(int j = l[i]; j <= r[i]; j++){ 67 if(y-lazy[i] == a[j]){ 68 ll = j; 69 break; 70 } 71 } 72 break; 73 } 74 } 75 if(ll == 0) return -1; 76 for(int i = tot; i >= 1; i--){ 77 int t = *lower_bound(vc[i].begin(), vc[i].end(), y-lazy[i]); 78 if(y - lazy[i] == t){ 79 for(int j = r[i]; j >= l[i]; j--){ 80 if(y-lazy[i] == a[j]){ 81 rr = j; 82 break; 83 } 84 } 85 break; 86 } 87 } 88 return rr-ll; 89 } 90 int main(){ 91 int q; 92 scanf("%d%d", &n, &q); 93 for(int i = 1; i <= n; i++) 94 scanf("%I64d", &a[i]); 95 Build(); 96 int op, ll, rr, k; 97 while(q--){ 98 scanf("%d", &op); 99 if(op == 1) { 100 scanf("%d%d%d", &ll, &rr, &k); 101 Update(ll,rr,k); 102 } 103 else { 104 scanf("%d", &k); 105 printf("%d\n", Query(k)); 106 } 107 } 108 109 return 0; 110 }
CodeForces 551 E GukiZ and GukiZiana
标签:using mes 最大的 span main upd c++ 从右到左 std
原文地址:https://www.cnblogs.com/MingSD/p/9112903.html