• zstu2016校赛圣杯战争


      这题不知道为什么就是T,简直有毒。

      思想和巴比伦那题差不多。

      话说,寻找一个区间内满足一个条件的最左(右)边的一个数,用线段树来写,应该是可以的,之前博客里大连网赛那题的线段树写法应该是有点小问题的。现在按照下面的套路来,虽然是T的= =。当然也可以用单调栈来实现。

      代码如下(T的):

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #define ls (o<<1)
      5 #define rs (o<<1|1)
      6 #define t_mid (l+r>>1)
      7 #define lson ls,l,t_mid
      8 #define rson rs,t_mid+1,r
      9 using namespace std;
     10 typedef long long ll;
     11 const int N = 200000 + 100;
     12 
     13 int n,m,q;
     14 ll atk[N];
     15 int nxt[N],pos[N];
     16 int c[N<<2],d[N<<2];
     17 // 线段树维护(nxt[i] - i + 1)的最大值和(nxt[i])的最大值
     18 
     19 void build(int o,int l,int r)
     20 {
     21     if(l == r) {c[o] = nxt[l]-l+1; d[o] = nxt[l]; return;}
     22     build(lson);
     23     build(rson);
     24     c[o] = max(c[ls],c[rs]); d[o] = max(d[ls],d[rs]);
     25 }
     26 
     27 int Find(int o,int l,int r,int ql,int qr,int where)
     28 {
     29     //if(ql > qr) return -1;
     30     if(l == r)
     31     {
     32         if(nxt[l] >= where) return l;
     33         else return -1;
     34     }
     35     int ans = -1;
     36     if(t_mid >= qr)
     37     {
     38         if(d[ls] >= where) ans = Find(lson,ql,qr,where);
     39     }
     40     else if(ql > t_mid)
     41     {
     42         if(d[rs] >= where) ans = Find(rson,ql,qr,where);
     43     }
     44     else
     45     {
     46         if(d[ls] >= where) ans = Find(lson,ql,t_mid,where);
     47         if(ans == -1 && d[rs] >= where) ans = Find(rson,t_mid+1,qr,where);
     48     }
     49     return ans;
     50 }
     51 
     52 int Find2(int o,int l,int r,int ql,int qr)
     53 {
     54     if(ql == l && qr == r)
     55     {
     56         return d[o];
     57     }
     58     int ans = 0;
     59     if(t_mid >= qr) ans = Find2(lson,ql,qr);
     60     else if(t_mid < ql) ans = Find2(rson,ql,qr);
     61     else
     62     {
     63         ans = max(Find2(lson,ql,t_mid), Find2(rson,t_mid+1,qr));
     64     }
     65 
     66     return ans;
     67 }
     68 
     69 int query(int o,int l,int r,int ql,int qr)
     70 {
     71     if(ql == l && qr == r)
     72     {
     73         return c[o];
     74     }
     75     if(qr <= t_mid) return query(lson,ql,qr);
     76     else if(ql > t_mid) return query(rson,ql,qr);
     77     else return max(query(lson,ql,t_mid), query(rson,t_mid+1,qr));
     78 }
     79 
     80 int solve(int ql,int qr)
     81 {
     82     int temp = -1;
     83     //int temp = Find(1,1,n,ql,qr,qr);
     84 
     85     int ans = 0, ans2 = 0, ans3 = 0;
     86 
     87     if(temp == -1) ans2 = query(1,1,n,ql,qr);
     88     else
     89     {
     90         ans = qr - temp + 1;
     91         if(temp != ql) ans2 = query(1,1,n,ql,temp-1);
     92     }
     93     if(ql > 1)
     94     {
     95         ans3 = Find2(1,1,n,1,ql-1);
     96         if(ans3 > qr) ans3 = qr;
     97         if(ans3 >= ql) ans3 = ans3 - ql + 1;
     98     }
     99 
    100     return max(max(max(ans,ans2),ans3),0);
    101 }
    102 
    103 int main()
    104 {
    105     int T;scanf("%d",&T);
    106     while(T--)
    107     {
    108         memset(nxt,-1,sizeof(nxt));
    109         //memset(atk,0,sizeof(atk));
    110         scanf("%d%d%d",&n,&m,&q);
    111         //nxt[0] = n;
    112         for(int i=1;i<=n;i++) {scanf("%d",atk+i);atk[i]+=atk[i-1];}
    113         for(int i=1;i<=m;i++) scanf("%d",pos+i);
    114         for(int i=1;i<=m;i++)
    115         {
    116             int hp;scanf("%d",&hp);
    117             int now = pos[i] - 1;
    118             int l = pos[i], r = n, ans = -1;
    119             while(l <= r)
    120             {
    121                 int mid = l + r >> 1;
    122                 if(atk[mid] - atk[now] <= hp) {ans = mid; l = mid + 1;}
    123                 else r = mid - 1;
    124             }
    125             nxt[pos[i]] = max(ans,nxt[pos[i]]);
    126 
    127             ans = -1;
    128             l = 1, r = pos[i];
    129             now = pos[i];
    130             while(l <= r)
    131             {
    132                 int mid = l + r >> 1;
    133                 if(atk[now] - atk[mid-1] <= hp) {ans = mid; r = mid - 1;}
    134                 else l = mid + 1;
    135             }
    136             nxt[ans] = max(pos[i],nxt[ans]);
    137             //printf("%d %d ??
    ",pos[i],ans);
    138         }
    139 
    140         /*int now = -1;
    141         for(int i=1;i<=n;i++)
    142         {
    143             if(nxt[i] != -1) now = max(now,nxt[i]);
    144             else
    145             {
    146                 nxt[i] = now;
    147                 if(now == i) now = -1;
    148             }
    149         }*/
    150         //----------------------处理线段-------------------------
    151         build(1,1,n);
    152         //for(int i=1;i<=n;i++) printf("%d !!
    ",nxt[i]);
    153         int ans = 0;
    154         int ql, qr;
    155         while(q--)
    156         {
    157             scanf("%d%d",&ql,&qr);
    158             ql ^= ans;
    159             qr ^= ans;
    160 
    161             //if(ql > qr) swap(ql, qr);
    162             /*if(ql < 0) ql = -ql;
    163             if(qr < 0) qr = -qr;
    164             if(ql > qr) swap(ql, qr);
    165             if(ql < 1||ql > n) ql = 1;
    166             if(qr <1 ||qr > n) qr = n; */
    167 
    168             //ql = 1,qr = n;
    169             if(ql > qr) swap(ql, qr);
    170             printf("%d
    ",ans=solve(ql,qr));
    171         }
    172     }
    173     return 0;
    174 }
  • 相关阅读:
    WAP协议研究笔记—彩信的传输
    应用程序重起自身等几则技巧
    谁妨碍了我们快乐
    国庆长假总结
    关于输入法的两个问题
    反刍
    为什么,一个思维方式的问题,一个习惯的问题,已经意识到了这一点,
    电影池子,
    幻想下,
    意识流,
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6111214.html
Copyright © 2020-2023  润新知