zoukankan      html  css  js  c++  java
  • 11月下旬题解

    (压根就没做几道题,无地自容QAQ)

    gym101138 J

    直接上树链剖分+线段树,注意处理好端点问题(其实有(Q+N)logN的做法)

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 typedef long long ll;
      5 struct way{int po,next;} e[200010];
      6 struct node{ll lm,rm,s,mx;} tr[100010*4];
      7 int s[100010],a[100010],b[100010],c[100010],be[100010],d[100010],p[100010],fa[100010];
      8 int n,m,len,t,q;
      9 const ll mi=-1000000000ll*100001ll;
     10 const node inf={mi,mi,0,mi};
     11 void add(int x, int y)
     12 {
     13      e[++len].po=y;
     14      e[len].next=p[x];
     15      p[x]=len;
     16 }
     17 
     18 void dfs1(int x)
     19 {
     20      s[x]=1;
     21      for (int i=p[x]; i; i=e[i].next)
     22      {
     23          int y=e[i].po;
     24          if (fa[x]!=y)
     25          {
     26             fa[y]=x; d[y]=d[x]+1;
     27             dfs1(y);
     28             s[x]+=s[y];
     29          }
     30      }
     31 }
     32 
     33 void dfs2(int x)
     34 {
     35      c[x]=++t;
     36      b[t]=x;
     37      int q=0;
     38      for (int i=p[x]; i; i=e[i].next)
     39      {
     40          int y=e[i].po;
     41          if (c[y]==0&&s[q]<s[y]) q=y;
     42      }
     43      if (q)
     44      {
     45         be[q]=be[x];
     46         dfs2(q);
     47      }
     48      for (int i=p[x]; i; i=e[i].next)
     49      {
     50          int y=e[i].po;
     51          if (fa[x]!=y&&y!=q)
     52          {
     53             be[y]=y;
     54             dfs2(y);
     55          }
     56      }
     57 }
     58 
     59 void update(node &a,node b,node c)
     60 {
     61     a.s=b.s+c.s;
     62     a.lm=max(b.lm,b.s+c.lm);
     63     a.rm=max(c.rm,c.s+b.rm);
     64     a.mx=max(b.rm+c.lm,max(b.mx,c.mx));
     65     a.mx=max(a.mx,max(a.rm,a.lm));
     66 }
     67 
     68 void build(int i,int l,int r)
     69 {
     70     if (l==r) tr[i].mx=tr[i].s=tr[i].lm=tr[i].rm=a[b[l]];
     71     else {
     72         int m=(l+r)>>1;
     73         build(i*2,l,m);
     74         build(i*2+1,m+1,r);
     75         update(tr[i],tr[i*2],tr[i*2+1]);
     76     }
     77 }
     78 
     79 node ask(int i,int l,int r,int x,int y)
     80 {
     81     if (x<=l&&y>=r) return tr[i];
     82     else {
     83         int m=(l+r)>>1;
     84         if (x<=m&&y>m)
     85         {
     86             node s,a=ask(i*2,l,m,x,y),b=ask(i*2+1,m+1,r,x,y);
     87             update(s,a,b);
     88             return s;
     89         }
     90         else if (x<=m) return ask(i*2,l,m,x,y);
     91         else if (y>m) return ask(i*2+1,m+1,r,x,y);
     92     }
     93 }
     94 
     95 ll work(int x,int y)
     96 {
     97     node sx=inf,sy=inf,s;
     98     while (be[x]!=be[y])
     99     {
    100           if (d[be[x]]>=d[be[y]])
    101           {
    102              update(sx,ask(1,1,n,c[be[x]],c[x]),sx);
    103              x=fa[be[x]];
    104           }
    105           else {
    106              update(sy,ask(1,1,n,c[be[y]],c[y]),sy);
    107              y=fa[be[y]];
    108           }
    109     }
    110     swap(sx.lm,sx.rm);
    111     if (c[x]>c[y])
    112     {
    113         s=ask(1,1,n,c[y],c[x]); swap(s.lm,s.rm);
    114         update(sx,sx,s);
    115     }
    116     else update(sy,ask(1,1,n,c[x],c[y]),sy);
    117     update(s,sx,sy);
    118     return s.mx;
    119 }
    120 
    121 int main()
    122 {
    123     scanf("%d",&n);
    124     int x,y;
    125     for (int i=1; i<n; i++)
    126     {
    127         scanf("%d%d",&x,&y);
    128         add(x,y);
    129         add(y,x);
    130     }
    131     for (int i=1; i<=n; i++) scanf("%d",&a[i]);
    132     dfs1(1);
    133     t=0; be[1]=1;
    134     dfs2(1);
    135     build(1,1,n);
    136     scanf("%d",&q);
    137     for (int i=1; i<=q; i++)
    138     {
    139         scanf("%d%d",&x,&y);
    140         printf("%I64d
    ",work(x,y));
    141     }
    142 }
    View Code

    cf739 c

    先差分,把差为0处理掉,就相当于拼接单调不下降序列,线段树维护之

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 struct node{int lm,rm,mx;} tr[300010*4];
     6 int a[300010],n,q;
     7 ll b[300010];
     8 
     9 int dcmp(ll a)
    10 {
    11     if (a>0) return 1;
    12     if (a<0) return -1;
    13     return 0;
    14 }
    15 
    16 void update(int i,int l,int r)
    17 {
    18     int m=(l+r)>>1;
    19     tr[i].mx=max(tr[i*2].mx,tr[i*2+1].mx);
    20     if (dcmp(b[m])<=dcmp(b[m+1])) tr[i].mx=max(tr[i].mx,tr[i*2].rm+tr[i*2+1].lm);
    21     tr[i].lm=tr[i*2].lm;
    22     if (tr[i].lm==m-l+1&&dcmp(b[m])<=dcmp(b[m+1])) tr[i].lm=tr[i].lm+tr[i*2+1].lm;
    23     tr[i].rm=tr[i*2+1].rm;
    24     if (tr[i].rm==r-m&&dcmp(b[m])<=dcmp(b[m+1])) tr[i].rm=tr[i].rm+tr[i*2].rm;
    25 }
    26 
    27 void build(int i,int l,int r)
    28 {
    29     if (l==r)
    30     {
    31         int w=dcmp(b[l])!=0;
    32         tr[i]=(node){w,w,w};
    33     }
    34     else {
    35         int m=(l+r)>>1;
    36         build(i*2,l,m);
    37         build(i*2+1,m+1,r);
    38         update(i,l,r);
    39     }
    40 }
    41 
    42 void work(int i,int l,int r,int x,int z)
    43 {
    44     if (l==r)
    45     {
    46         b[l]+=z;
    47         int w=dcmp(b[l])!=0;
    48         tr[i]=(node){w,w,w};
    49     }
    50     else {
    51         int m=(l+r)>>1;
    52         if (x<=m) work(i*2,l,m,x,z); else work(i*2+1,m+1,r,x,z);
    53         update(i,l,r);
    54     }
    55 }
    56 
    57 int main()
    58 {
    59     scanf("%d",&n);
    60     for (int i=1; i<=n; i++) scanf("%d",&a[i]);
    61     for (int i=1; i<n; i++) b[i]=a[i]-a[i+1];
    62     if (n>1) build(1,1,n-1);
    63     scanf("%d",&q);
    64     for (int i=1; i<=q; i++)
    65     {
    66         int l,r,z;
    67         scanf("%d%d%d",&l,&r,&z);
    68         if (n==1) puts("1");
    69         else {
    70             if (l>1) work(1,1,n-1,l-1,-z);
    71             if (r<n) work(1,1,n-1,r,z);
    72             printf("%d
    ",tr[1].mx+1);
    73         }
    74 
    75     }
    76 }
    View Code

    gym101138h

    表示1~b意味着选出的面额从小到大排列后,任意s(i-1)+1>=di,然后可以用meet in middle加速(细节颇多)

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 struct node{
     6     ll d,a;int id;
     7     friend bool operator <(node a,node b)
     8     {
     9         return a.d<b.d;
    10     }
    11 } a[50],c[(1<<21)+5];
    12 int t,n1,n2,n,s1,s2,b,mi[(1<<21)+5],w[50];
    13 ll ans;
    14 const ll inf=9223372036854775807ll;
    15 
    16 void pdf(int i,int st, ll sd, ll sa)
    17 {
    18     if (i==n1+1)
    19     {
    20         c[++t]=(node){sd,sa,st};
    21         if (sd>=b&&ans>sa)
    22         {
    23             ans=sa;
    24             s1=st; s2=0;
    25         }
    26         return;
    27     }
    28     pdf(i+1,st,sd,sa);
    29     if (sd+1>=a[i].d) pdf(i+1,st|(1<<(i-1)),sd+a[i].d,sa+a[i].a);
    30 }
    31 
    32 void dfs(int i,int st,ll sd,ll sa,ll key)
    33 {
    34     if (i==n2+1)
    35     {
    36         node x=(node){max(key,b-sd),0,0};
    37         int pos=lower_bound(c+1,c+1+t,x)-c;
    38         if (pos==t+1) return;
    39         if (c[mi[pos]].a+sa<ans)
    40         {
    41             s1=c[mi[pos]].id; s2=st;
    42             ans=c[mi[pos]].a+sa;
    43         }
    44         return;
    45     }
    46     dfs(i+1,st,sd,sa,key);
    47     dfs(i+1,st|(1<<(i-1)),sd+a[n1+i].d,sa+a[n1+i].a,max(key,a[i+n1].d-sd-1));
    48 }
    49 
    50 int main()
    51 {
    52     scanf("%d%d",&n,&b);
    53     for (int i=1; i<=n; i++)
    54     {
    55         int x,y;
    56         scanf("%d%d",&x,&y);
    57         a[i]=(node){x,y,i};
    58     }
    59     sort(a+1,a+1+n);
    60     ans=inf,s1=0,s2=0;
    61     n1=n/2+(n%2),n2=n-n1,t=0;
    62     pdf(1,0,0,0);
    63     sort(c+1,c+1+t);
    64     mi[t]=t;
    65     for (int i=t-1; i; i--)
    66       mi[i]=c[mi[i+1]].a>=c[i].a?i:mi[i+1];
    67     dfs(1,0,0,0,0);
    68     if (ans<inf)
    69     {
    70         int s=0;
    71         for (int i=0; i<n1; i++)
    72             if (s1&(1<<i)) w[++s]=a[i+1].id;
    73         for (int i=0; i<n2; i++)
    74             if (s2&(1<<i)) w[++s]=a[i+n1+1].id;
    75         printf("%d
    ",s);
    76         for (int i=1; i<=s; i++)
    77         {
    78             printf("%d",w[i]);
    79             if (i<s) printf(" "); else puts("");
    80         }
    81     }
    82     else puts("-1");
    83 }
    View Code

     之前还有些题有意思的以后再放吧

  • 相关阅读:
    人人网笔试题
    创新工厂笔试题
    奇异广告面试
    微策略笔试题
    多玩笔试题
    有道笔试+面试
    巨人网络开发工程师试题
    Hulu笔试题
    百度笔试题
    兰亭集势笔试题
  • 原文地址:https://www.cnblogs.com/phile/p/6123919.html
Copyright © 2011-2022 走看看