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\n",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 }
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\n",ans); 21 } 22 return 0; 23 }
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 '\n' 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\n",maxflow); 112 } 113 }