• 2016-浙江理工新生赛-部分题解


    巴比伦花园

            link :http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4239

           对于新生还是比较难;

    我是用 RMQ + 二分 写的; 因为  fi[i]  数组代表从i开始最长到哪里,因为要求最长,所以第一个一定是1, i 是单调的,fi 数组也是单调的,所以可以二分;二分找刚刚在区间的,完全在区间用RMQ 离线查询;


      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cctype>
      4 #include <cmath>
      5 #include <set>
      6 #include <map>
      7 #include <list>
      8 #include <queue>
      9 #include <deque>
     10 #include <stack>
     11 #include <string>
     12 #include <vector>
     13 #include <iostream>
     14 #include <algorithm>
     15 #include <stdlib.h>
     16 #include <time.h>
     17  
     18 using namespace std;
     19 typedef long long LL;
     20 const int INF=2e9+1e8;
     21 const int MOD=1e9+7;
     22 const int MAXSIZE=1e6+5;
     23 const double eps=0.0000000001;
     24 void fre()
     25 {
     26     freopen("in.txt","r",stdin);
     27     freopen("out.txt","w",stdout);
     28 }
     29 #define memst(a,b) memset(a,b,sizeof(a))
     30 #define fr(i,a,n) for(int i=a;i<n;i++)
     31  
     32  
     33 const int MAXN=1e5+10;
     34 
     35 int n,k,q;
     36 LL input[MAXN];
     37 int fi[MAXN];
     38 
     39 struct RMQ
     40 {
     41     int dp[MAXN][20];
     42     void init()
     43     {
     44         for(int i=1;i<=n;i++) dp[i][0]=fi[i];
     45         for(int i=1;i<20;i++) 
     46             for(int j=1;j<=n;j++)    
     47                 if(j+(1<<i)-1<=n) dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
     48     }
     49     int query(int l,int r)
     50     {
     51         if(l>r) return -1;
     52         if(l==r) return fi[l];
     53         int _k=(int)log2(r-l+1);
     54         return max(dp[l][_k],dp[r-(1<<_k)+1][_k]);
     55     }
     56 }rmq;
     57 
     58 int query(int l,int st)
     59 {
     60     for(int i=l;i<=n;i++)
     61         if(input[i]<1+k*((LL)i-st)) return i-st;
     62     return n-st+1;
     63 }
     64 int findR(int L,int R,int& b)
     65 {
     66     int l=1,r=n;
     67     while(1)
     68     {
     69         int mid=(l+r)>>1;
     70         if(fi[mid]+mid-1>=R&&fi[mid-1]+mid-2<R) 
     71         {
     72             b=mid-1;
     73             return R-max(L,mid)+1;
     74         }
     75         if(fi[mid]+mid-1>=R) r=mid;
     76         else l=mid+1;
     77     }
     78 }
     79 int findL(int L,int R,int& a)
     80 {
     81     int l=1,r=n;
     82     while(1)
     83     {
     84         int mid=(l+r)>>1;
     85         if(mid<=L&&mid+1>L) 
     86         {
     87             a=mid+1;
     88             return min(R,mid+fi[mid]-1)-L+1;
     89         }
     90         if(mid<=L) l=mid+1;
     91         else r=mid;
     92     }
     93 }
     94 int main()
     95 {
     96     int ncase;
     97     scanf("%d",&ncase);
     98     while(ncase--)
     99     {
    100         scanf("%d%d%d",&n,&k,&q);
    101         fi[0]=-INF;
    102         for(int i=1;i<=n;i++)
    103             scanf("%lld",&input[i]);
    104         for(int i=1;i<=n;i++)
    105             fi[i]=query(max(i-1+fi[i-1],i),i);
    106         fi[n+1]=INF;
    107         rmq.init();
    108         while(q--)
    109         {
    110             int l,r,a,b;
    111             scanf("%d%d",&l,&r);
    112             int maxnum=max(findL(l,r,a),findR(l,r,b));
    113             printf("%d
    ",max(rmq.query(a,b),maxnum));
    114         }
    115     }
    116     return 0;
    117 }
    118 
    119 /**************************************************/
    120 /**             Copyright Notice                 **/
    121 /**  writer: wurong                              **/
    122 /**  school: nyist                               **/
    123 /**  blog  : http://blog.csdn.net/wr_technology  **/
    124 /**************************************************/
    View Code


    D  题也是同一种套路; RMQ + 二分

    4241: 圣杯战争

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cctype>
      4 #include <cmath>
      5 #include <set>
      6 #include <map>
      7 #include <list>
      8 #include <queue>
      9 #include <deque>
     10 #include <stack>
     11 #include <string>
     12 #include <vector>
     13 #include <iostream>
     14 #include <algorithm>
     15 #include <stdlib.h>
     16 #include <time.h>
     17 
     18 using namespace std;
     19 typedef long long LL;
     20 const int INF=2e9+1e8;
     21 const int MOD=1e9+7;
     22 const int MAXSIZE=1e6+5;
     23 const double eps=0.0000000001;
     24 void fre()
     25 {
     26     freopen("in.txt","r",stdin);
     27     freopen("out.txt","w",stdout);
     28 }
     29 #define memst(a,b) memset(a,b,sizeof(a))
     30 #define fr(i,a,n) for(int i=a;i<n;i++)
     31 
     32 
     33 const int MAXN=2e5+10;
     34 
     35 int n,m,q,total,ans;
     36 LL atk[MAXN],presum[MAXN];
     37 int ap[MAXN],pos[MAXN];
     38 pair<int,int> seg[MAXN],Interval[MAXN];
     39 
     40 struct RMQ
     41 {
     42     int dp[MAXN][20];
     43     void init()
     44     {
     45         for(int i=1;i<total;i++) dp[i][0]=Interval[i].second-Interval[i].first+1;
     46         for(int i=1;i<20;i++)
     47             for(int j=1;j<total;j++)
     48                 if(j+(1<<i)-1<total) dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
     49     }
     50     int query(int l,int r)
     51     {
     52         if(l>r) return 0;
     53         int _k=(int)log2(r-l+1);
     54         return max(dp[l][_k],dp[r-(1<<_k)+1][_k]);
     55     }
     56 }rmq;
     57 bool cmp(pair<int,int> a,pair<int,int> b)//按照 first 从小到大,first 一样的按照 second 的从大到小
     58 {
     59     if(a.first!=b.first) return a.first<b.first;
     60     else return a.second>b.second;
     61 }
     62 bool cmp1(pair<int,int> a,int val)
     63 {
     64     return a.first<val;
     65 }
     66 bool cmp2(pair<int,int> a,int val)
     67 {
     68     return a.second<val;
     69 }
     70 int query(int l,int r)
     71 {
     72     l=l^ans,r=r^ans;
     73     if(l>r) swap(l,r);
     74     l=max(1,l),r=min(n,r);
     75  //   printf("query %d %d
    ",l,r);
     76     int fl,fr,maxnum;
     77     fl=lower_bound(Interval+1,Interval+total,l,cmp1)-Interval-1;
     78     fr=lower_bound(Interval+1,Interval+total,r,cmp2)-Interval;
     79   //
     80     int ans1=min(Interval[fl].second,r)-max(l,Interval[fl].first)+1;
     81     int ans2=min(r,Interval[fr].second)-max(l,Interval[fr].first)+1;
     82     if(fl>=total||fl<=0) ans1=-1;
     83     if(fr>=total||fr<=0) ans2=-1;
     84     maxnum=max(ans1,ans2);
     85    // printf("ans= %d %d %d
    ",ans1,ans2,rmq.query(fl+1,fr-1));
     86     return max(rmq.query(fl+1,fr-1),maxnum);
     87 }
     88 void  debug(int k)
     89 {
     90 //    for(int i=0;i<k;i++)
     91 //        printf("seg[%d] : %d %d
    ",i,seg[i].first,seg[i].second);
     92 //    printf("
    ***********************************
    ");
     93     printf("total=%d
    ",total);
     94     for(int i=1;i<total;i++)
     95         printf("seg[%d] : %d %d
    ",i,Interval[i].first,Interval[i].second);
     96     printf("
    ***********************************
    ");
     97 }
     98 LL getval(int l,int r)
     99 {
    100     return presum[r]-presum[l-1];
    101 }
    102 int Lpos(int _pos,int _ap)
    103 {
    104     int l=1,r=_pos;
    105     while(1)
    106     {
    107         int mid=(l+r)>>1;
    108         if((mid==1&&getval(mid,_pos)<=_ap)||(getval(mid,_pos)<=_ap&&getval(mid-1,_pos)>_ap)) return mid;
    109         if(getval(mid,_pos)<=_ap) r=mid;
    110         else l=mid+1;
    111     }
    112 }
    113 int Rpos(int _pos,int _ap)
    114 {
    115     int l=_pos,r=n;
    116     while(1)
    117     {
    118         int mid=(l+r)>>1;
    119         if((mid==n&&getval(_pos,mid)<=_ap)||(getval(_pos,mid)<=_ap&&getval(_pos,mid+1)>_ap)) return mid;
    120         if(getval(_pos,mid)<=_ap) l=mid+1;
    121         else r=mid;
    122     }
    123 }
    124 int main()
    125 {
    126     int ncase;
    127     scanf("%d",&ncase);
    128     while(ncase--)
    129     {
    130         scanf("%d%d%d",&n,&m,&q);
    131         presum[0]=0;
    132         for(int i=1;i<=n;i++)
    133         {
    134             scanf("%lld",&atk[i]);
    135             presum[i]=atk[i]+presum[i-1];
    136         }
    137         for(int i=0;i<m;i++)
    138             scanf("%d",&pos[i]);
    139         for(int i=0;i<m;i++)
    140             scanf("%d",&ap[i]);
    141         int k=0;
    142         presum[n+1]=INF;
    143         for(int i=0;i<m;i++)
    144         {
    145             if(ap[i]<atk[pos[i]]) continue;
    146             seg[k].first=Lpos(pos[i],ap[i]),seg[k++].second=pos[i];
    147             seg[k].first=pos[i],seg[k++].second=Rpos(pos[i],ap[i]);
    148         }
    149         // OK;
    150         if(k==0)
    151         {
    152             int l,r;
    153             while(q--) scanf("%d%d",&l,&r),printf("0
    ");
    154             continue;
    155         }
    156         sort(seg,seg+k,cmp);//OK;
    157         total=2;
    158         Interval[1]=seg[0];
    159         for(int i=1;i<k;i++)
    160             if(seg[i].second>Interval[total-1].second)
    161                 Interval[total++]=seg[i];
    162         rmq.init();
    163         Interval[0].first=Interval[0].second=-1;
    164         Interval[total].first=Interval[total].second=INF;
    165         ans=0;
    166       //  debug(k);
    167         while(q--)
    168         {
    169             int l,r;
    170             scanf("%d%d",&l,&r);
    171             printf("%d
    ",ans=query(l,r));
    172         }
    173     }
    174     return 0;
    175 }
    176 
    177 /**************************************************/
    178 /**             Copyright Notice                 **/
    179 /**  writer: wurong                              **/
    180 /**  school: nyist                               **/
    181 /**  blog  : http://blog.csdn.net/wr_technology  **/
    182 /**************************************************/
    View Code


     

    4248: KI的目标

      1 /*
      2 如果 dis(a,b)>=val[a]-val[b] && dis[b,c]>=val[b]-val[c];
      3 那么 dis(a,c)>=val[a]-val[c];
      4 所以 只需要判断 val[现在的点]-val[下一个点]>边权值  如果真就不统计;
      5 */
      6 #include <cstdio>
      7 #include <cstring>
      8 #include <cctype>
      9 #include <cmath>
     10 #include <set>
     11 #include <map>
     12 #include <list>
     13 #include <queue>
     14 #include <deque>
     15 #include <stack>
     16 #include <string>
     17 #include <vector>
     18 #include <iostream>
     19 #include <algorithm>
     20 #include <stdlib.h>
     21 #include <time.h>
     22 
     23 using namespace std;
     24 typedef long long LL;
     25 const int INF=2e9+1e8;
     26 const int MOD=1e9+7;
     27 const int MAXSIZE=1e6+5;
     28 const double eps=0.0000000001;
     29 void fre()
     30 {
     31     freopen("in.txt","r",stdin);
     32     freopen("out.txt","w",stdout);
     33 }
     34 #define memst(a,b) memset(a,b,sizeof(a))
     35 #define fr(i,a,n) for(int i=a;i<n;i++)
     36 
     37 
     38 
     39 const int MAXN = 1000000+10;
     40 struct Node
     41 {
     42     int to,next,val;
     43 }edge[MAXN<<1];
     44 int first[MAXN],ntot;
     45 void init()
     46 {
     47     ntot=0;
     48     memset(first,-1,sizeof(first));
     49 }
     50 void addedge(int s,int t,int val)
     51 {
     52     edge[ntot].to=t,edge[ntot].val=val;
     53     edge[ntot].next=first[s];
     54     first[s]=ntot++;
     55 }
     56 int val[MAXN];
     57 int n;
     58 
     59 int dfs (int o,int now)
     60 {
     61     int res=1;
     62     for (int i=first[now],to,value; ~i; i=edge[i].next)
     63     {
     64         to=edge[i].to, value=edge[i].val;
     65         if (to==o) continue;
     66         if (val[now]-val[to]>value)  //val(v)<val(u)+path(u)-Path(v)  那么val(u)+path(u)取最大
     67         {
     68             continue;
     69         }
     70         res += dfs (now, to);
     71     }
     72     return res;
     73 }
     74 
     75 int main ()
     76 {
     77     int ncase;
     78     scanf ("%d", &ncase);
     79     while(ncase--)
     80     {
     81         scanf ("%d", &n);
     82         init();
     83         for (int i=1,u,v,w; i<n; i++)
     84         {
     85             scanf ("%d%d%d", &u, &v, &w);
     86             addedge(u,v,w);
     87             addedge(v,u,w);
     88         }
     89         for (int i=1; i<=n; i++) scanf ("%d", val+i);
     90         printf ("%d
    ", dfs (1, 1));
     91     }
     92     return 0;
     93 }
     94 
     95 
     96 
     97 /**************************************************/
     98 /**             Copyright Notice                 **/
     99 /**  writer: wurong                              **/
    100 /**  school: nyist                               **/
    101 /**  blog  : http://blog.csdn.net/wr_technology  **/
    102 /**************************************************/
    View Code
  • 相关阅读:
    解决Strokeit在win8下的图标问题和开机启动问题
    解决 笔记本键盘打字母却跳出数字来,每次都要按一遍Fn+Num LK 的问题
    Google API在线生成二维码的方法
    解决安装vc2005运行库时提示Command line option syntax error.Type Command/?for Help
    PHP自动发邮件
    java核心技术之java平台的理解
    基于MPI的矩阵相乘summa算法实现(附源程序)
    采用概率算法,估计整数子集1~n的大小
    采用MPI_Send 和MPI_Recv 编写代码来实现包括MPI_Bcast、MPI_Alltoall、MPI_Gather、MPI_Scatter 等MPI 群集通信函数的功能
    PWM控制蜂鸣器实验(附源代码)
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7207936.html
Copyright © 2020-2023  润新知