码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 551 E GukiZ and GukiZiana

时间:2018-05-30 21:05:06      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:using   mes   最大的   span   main   upd   c++   从右到左   std   

GukiZ and GukiZiana

题意:有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 }
CF 551 E

 

CodeForces 551 E GukiZ and GukiZiana

标签:using   mes   最大的   span   main   upd   c++   从右到左   std   

原文地址:https://www.cnblogs.com/MingSD/p/9112903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!