• 2019HDU多校第一场


    1002.Operation

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6579

    题意:给定一个长度为$n$的数列,$m$次操作,每次操作如下:

    $0 l r$:查询区间$[l,r]$内若干个数的最大异或和。

    $1 x$:给数列末尾添加一个数$x$。

    数据范围:$1<=n,m<=5e5,1<=a_i<=2^{30}$。

    分析:开始直接考虑用线段树维护区间线性基的并,然后每次查询求区间线性基,再求最大。(但是tle

    贪心考虑答案。区间$[1,i]$的线性基一定是由$[1,i-1]$的线性基插入$a_i$后得到的。那么可以通过维护线性基的前缀和来得到答案。

    (qaq,指路网友博客:https://blog.csdn.net/tyxacm/article/details/97156620

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=5e5+10;
     5 struct Linear_basis{
     6     ll b[maxn][35];int kk[maxn][35];
     7     void add(ll x,int id){
     8         int tot=id;
     9         for (int i=32;i>=0;i--){
    10             b[tot][i]=b[tot-1][i];
    11             kk[tot][i]=kk[tot-1][i];
    12         }
    13         for (int i=32;i>=0;i--){
    14             if (x&(1ll<<i)){
    15                 if (!b[tot][i]){
    16                     b[tot][i]=x;
    17                     kk[tot][i]=id;
    18                     break;
    19                 }
    20                 else{
    21                     if (id>kk[tot][i]){
    22                         swap(b[tot][i],x);
    23                         swap(kk[tot][i],id);
    24                     }
    25                     x^=b[tot][i];
    26                 }
    27             }
    28         }
    29     }
    30     ll query(int l,int r){
    31         ll res=0;
    32         for (int i=32;i>=0;i--){
    33             if (kk[r][i]>=l) res=max(res,res^b[r][i]);
    34         }
    35         return res;
    36     }
    37     void clear(int n){
    38         for (int i=1;i<=n;i++) memset(b[i],0,sizeof(b[i])),memset(kk[i],0,sizeof(kk[i]));
    39     }
    40 }LB;
    41 int main(){
    42     int t,n,m,kk,l,r,x;scanf("%d",&t);
    43     while (t--){
    44         scanf("%d%d",&n,&m);
    45         LB.clear(n);
    46         for (int i=1;i<=n;i++){
    47             scanf("%d",&x);
    48             LB.add(x,i);
    49         }
    50         ll lastans=0;
    51         while (m--){
    52             scanf("%d",&kk);
    53             if (kk==0){
    54                 scanf("%d%d",&l,&r);
    55                 l=(l^lastans)%n+1;
    56                 r=(r^lastans)%n+1;
    57                 if (l>r) swap(l,r);
    58                 lastans=LB.query(l,r);
    59                 printf("%lld
    ",lastans);
    60             }
    61             else{
    62                 scanf("%d",&x);
    63                 x=x^lastans; n++;
    64                 LB.add(x,n);
    65             }
    66         }
    67     }
    68     return 0;
    69 } 
    1002

    1004.Vacation

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6581

    题意:一个路口,你前面有$n$辆车,给出每辆车的车长,距离路口的距离,以及每辆车的最大车速。要求这$n+1$辆车依此通过,问你的车头通过路口的时间花费了多少。

    数据范围:$1<=n<=10^5,1<= s_i, v_i, l_i <=10^9$。

    分析:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=1e5+7;
     5 struct node{int l,s,v;ll len;} p[maxn];
     6 int main()
     7 {
     8     int n;
     9     while (~scanf("%d",&n))
    10     {
    11         for (int i=0;i<=n;i++) p[i].l=p[i].s=p[i].v=p[i].len=0;
    12         for (int i=0;i<=n;i++) scanf("%d",&p[i].l);
    13         for (int i=0;i<=n;i++) scanf("%d",&p[i].s);
    14         for (int i=0;i<=n;i++) scanf("%d",&p[i].v);
    15         for (int i=1;i<=n;i++) p[i].len+=p[i-1].len+1ll*p[i].l;
    16         for (int i=1;i<=n;i++) p[i].len+=1ll*p[i].s;
    17         p[0].len=p[0].s;
    18         double ans=0.0;
    19         for (int i=0;i<=n;i++) ans=max(ans,1.0*p[i].len/(1.0*p[i].v));
    20         printf("%.10f
    ",ans);
    21     }
    22     return 0;
    23 }
    1004

    1005.Path

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6582

    题意:有$n$点,$m$条路,要求切断一些路,使得从$1-n$的路比最短路大的最小花费。切断每一条路的花费就是每一条路的长度。

    数据范围:$1<=n,m<=10^5,1<=c<=10^9$。

    分析:题目要求就是要去掉一些路,使得最短路不成立。跑最短路选取出所有的最短路的边,然后用这些边跑最小割即可。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #define en '
    '
      7 #define low(x) (x)&(-x)
      8 #define m(a,b) memset(a,b,sizeof a)
      9 using namespace std;
     10 typedef long long ll;
     11 const int N=2e4+10,M=N;
     12 const ll INF=1e18;
     13 struct Edge{int to;ll len;int nex;}e[M],edge[M<<1];
     14 struct node{int x,y;ll c;}p[M];
     15 int head[N],tot,head2[N],ttt,n,m;
     16 void add(int from,int to,ll len)
     17 {
     18     edge[++tot]=(Edge){to,len,head[from]};head[from]=tot;
     19     edge[++tot]=(Edge){from,0,head[to]};head[to]=tot;
     20 }
     21 void add_edge(int from,int to,ll len){
     22     e[++ttt]=(Edge){to,len,head2[from]};head2[from]=ttt;
     23 }
     24 priority_queue<pair<ll,int>>Q;
     25 ll d[N],da[N],db[N];
     26 void dijkstra(int s)
     27 {
     28     for (int i=0;i<=n;i++) d[i]=INF;
     29     d[s]=0;Q.push(make_pair(0,s));
     30     while(!Q.empty())
     31     {
     32         int x=Q.top().second;Q.pop();
     33         for(int i=head2[x];i;i=e[i].nex)
     34         {
     35             int y=e[i].to;ll z=e[i].len;
     36             if(d[y]>d[x]+z)
     37             {
     38                 d[y]=d[x]+z;
     39                 Q.push(make_pair(-d[y],y));
     40             }
     41         }
     42     }
     43 }
     44 int s,t;
     45 queue<int>q;
     46 bool bfs()
     47 {
     48     for (int i=0;i<=n;i++) d[i]=0;
     49     while(!q.empty())q.pop();
     50     q.push(s);d[s]=1;
     51     while(!q.empty())
     52     {
     53         int x=q.front();q.pop();
     54         for(int i=head[x];i;i=edge[i].nex)
     55         {
     56             int y=edge[i].to;ll l=edge[i].len;
     57             if(!d[y]&&l)
     58             {
     59                 q.push(y),d[y]=d[x]+1;
     60                 if(y==t) return 1;
     61             }
     62         }
     63     }
     64     return 0;
     65 }
     66 ll dinic(int x,ll flow)
     67 {
     68     if(x==t) return flow;
     69     ll res=flow,k;
     70     for(int i=head[x];i&&res;i=edge[i].nex)
     71     {
     72         int y=edge[i].to;ll l=edge[i].len;
     73         if(l&&d[y]==d[x]+1)
     74         {
     75             k=dinic(y,min(res,l));
     76             if(!k){d[y]=0;continue;}
     77             edge[i].len-=k,edge[i^1].len+=k,res-=k;
     78         }
     79     }
     80     return flow-res;
     81 }
     82 int main()
     83 {
     84     int T;scanf("%d",&T);
     85     while(T--)
     86     {
     87         scanf("%d%d",&n,&m);
     88         for (int i=0;i<=n;i++) head[i]=0,head2[i]=0;
     89         ttt=0;tot=1;
     90         for(int i=1;i<=m;++i)
     91         {
     92             scanf("%d%d%lld",&p[i].x,&p[i].y,&p[i].c);
     93             add_edge(p[i].x,p[i].y,p[i].c);
     94         }
     95         dijkstra(1);
     96         if(d[n]==INF) {puts("0");continue;}
     97         for (int i=0;i<=n;i++) da[i]=d[i],head2[i]=0;
     98         ttt=0;
     99         for(int i=1;i<=m;++i) add_edge(p[i].y,p[i].x,p[i].c);
    100         dijkstra(n);
    101         for (int i=1;i<=n;i++) db[i]=d[i];
    102         for(int i=1;i<=m;++i)
    103         {
    104             if(da[p[i].x]+db[p[i].y]+p[i].c==da[n])
    105                 add(p[i].x,p[i].y,p[i].c);
    106         }
    107         for (int i=0;i<=n;i++) d[i]=0;
    108         s=1,t=n;
    109         ll maxflow=0;
    110         while(bfs()) maxflow+=dinic(s,INF);
    111         printf("%lld
    ",maxflow);
    112     }
    113 }
    1005
  • 相关阅读:
    博客是一种心情
    双显示器和双鼠标
    C++ Primer Plus 第六版 代码笔记
    Bug,昂首走进2005
    让万能五笔2004免费版改首页的功能见鬼去吧。
    Gmail提供POP3和SMTP已经老长时间了
    快过年回家了,发点实用的东西给大家
    关于博客园Post的时候排版的一点小建议
    在.Net下进行MicroStation(GG)的开发(一)
    验证域的另一方法
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11233672.html
Copyright © 2020-2023  润新知