2018-2019 ACM-ICPC Brazil Subregional Programming Contest
Posted mengx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018-2019 ACM-ICPC Brazil Subregional Programming Contest相关的知识,希望对你有一定的参考价值。
突突突 赶在暑假结束前 多搞搞队内训练
C. Pizza Cutter (solve)
题意:给你一个面基x*y的披萨 横着切h刀 竖着切v刀 题目保证了不会三刀交于一个点~
因为这个原因其实我们每次只需要求横着和竖着的逆序对 每个逆序对都会贡献+1 因为三刀不会交于一点所以正常切(没逆序对的情况下)
ans=(h+1)*(v+1) 然后加上逆序对即可
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int n,m; struct node int x,y; bool friend operator<(const node u,const node v) return u.x<v.x; p[maxn],q[maxn]; int a[maxn]; int tree[maxn]; int lowbit(int x) return x&(-x); void add(int x) while(x<maxn) tree[x]++; x+=lowbit(x); int query(int x) int res=0; while(x) res+=tree[x]; x-=lowbit(x); return res; ll solve(node *p,int n) sort(p+1,p+1+n); for(int i=1;i<=n;i++) a[i]=p[i].y; memset(tree,0,sizeof(tree)); sort(a+1,a+1+n); for(int i=1;i<=n;i++) p[i].y=lower_bound(a+1,a+1+n,p[i].y)-a; ll ans=0; for(int i=1;i<=n;i++) add(p[i].y); // cout<<i<<" "<<query(p[i].y)<<endl; ans+=i-query(p[i].y); return ans; int main() int x,y; cin>>x>>y; cin>>n>>m; for(int i=1;i<=n;i++) scanf("%d %d",&p[i].x,&p[i].y); ll ans=0; ans+=solve(p,n); for(int i=1;i<=m;i++) scanf("%d %d",&q[i].x,&q[i].y); ans+=solve(q,m); ans+=1LL*(n+1)*(m+1); cout<<ans<<"\n"; return 0;
D. Unraveling Monty Hall (solve)
题意:统一不是1的个数
E. Enigma (solve)
题意模拟就可以了
#include<bits/stdc++.h> #define maxn 300005 #define mod 1000000007 using namespace std; typedef long long ll; char s1[maxn],s2[maxn]; int main() scanf("%s%s",s1,s2); ll len1=strlen(s1); ll len2=strlen(s2); ll sum=0; for(int i=0;i<=len1-len2;i++) ll num=0; int k=i; for(int j=0;j<len2;j++) if(s1[k]==s2[j]) num++; k++; if(num==0) sum++; cout<<sum;
I. Switches (solve)
题意:开始有L盏灯亮着 你有N个开关 每个开关控制着一些灯 每次使用开关会使灯开or关
求按顺序按1~N个开关 能否关闭所有灯
思路:模拟最多两轮 因为第三轮的时候 第一轮和第二轮贡献抵消 所以前两轮没关掉 就没答案啦
#include<bits/stdc++.h> #define maxn 300005 #define mod 1000000007 using namespace std; typedef int ll; bitset<1005> a[1005],q; ll n,m; ll len,x; int main() scanf("%d%d",&n,&m); scanf("%d",&len); for(int i=0;i<len;i++) scanf("%d",&x); q[x]=1; for(int i=1;i<=n;i++) scanf("%d",&len); for(int j=0;j<len;j++) scanf("%d",&x); a[i][x]=1; ll sum=0; ll t=min(2,n); ll flag=0; for(int i=1;i<=t;i++) for(int j=1;j<=n;j++) q^=a[j]; sum++; if(q.count()==0) flag=1; break; if(flag) break; if(flag) printf("%d",sum); else printf("-1");
题意:
给你N个加油站 每个加油站需要ai的油 现在有M个油田可以提供油 接下来k条路用于油田到加油站的运输工作 且需要花费时间wi
每次运输量为无穷大且每个油田的车数量无穷大 让你求最少时间满足加油站的需求
思路:我们可以对于运输路径按wi排序 二分需要的路径数 也就是二分最大时间
每次check是否满流即可
L. Subway Lines (solve)
题意:给出一个树 然后求树上两条边的交集
思路:直接树剖 每次先插入第一条边 然后查询第二条边和即可
#include<bits/stdc++.h> #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pb push_back #define P pair<int,int> #define INF 1e18 using namespace std; const int maxn = 100005; int head[maxn],Next[maxn<<1],To[maxn<<1],fa[maxn],id[maxn],top[maxn],tp,pos[maxn]; int tot,cnt,size[maxn],son[maxn],deep[maxn],n; int tree[maxn<<2],lazy[maxn<<2]; struct node int u,v; p[100005]; void add(int u,int v) Next[++cnt]=head[u]; head[u]=cnt; To[cnt]=v; void dfs1(int u,int f,int dep) fa[u]=f; deep[u]=dep+1; int mx=0; for(int i=head[u]; i!=-1; i=Next[i]) int v=To[i]; if(v==f) continue; dfs1(v,u,dep+1); size[u]+=size[v]; if(size[v]>mx) mx=size[v],son[u]=v; size[u]++; void dfs2(int u,int tp) id[u]=++tot; pos[tot]=u; top[u]=tp; if(son[u]) dfs2(son[u],tp); for(int i=head[u]; i!=-1; i=Next[i]) int v=To[i]; if(v!=son[u]&&v!=fa[u]) dfs2(v,v); void push_up(int rt) tree[rt]=tree[rt<<1]+tree[rt<<1|1]; void push_down(int rt,int l,int r) if(lazy[rt]!=-1) lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt]; int m=(l+r)>>1; tree[rt<<1]=(m-l+1)*lazy[rt]; tree[rt<<1|1]=(r-m)*lazy[rt]; lazy[rt]=-1; void update(int l,int r,int rt,int L,int R,int val) if(L<=l&&r<=R) tree[rt]=(r-l+1)*val; lazy[rt]=val; // cout<<rt<<" "<<val<<endl; return ; push_down(rt,l,r); int m=(l+r)>>1; if(L<=m) update(lson,L,R,val); if(R>m) update(rson,L,R,val); push_up(rt); int query(int l,int r,int rt,int L,int R) // i//f(l>r) return 0; if(tree[rt]==0) return 0; if(L<=l&&r<=R) return tree[rt]; int m=(l+r)>>1; push_down(rt,l,r); int sum=0; if(L<=m) sum+=query(lson,L,R); if(R>m) sum+=query(rson,L,R); push_up(rt); return sum; void Update(int u,int v,int val) while(top[u]!=top[v]) if(deep[top[u]]<deep[top[v]]) swap(u,v); // cout<<id[top[u]]<<" "<<id[u]<<endl; update(1,n,1,id[top[u]],id[u],val); u=fa[top[u]]; if(deep[u]>deep[v]) swap(u,v); update(1,n,1,id[u],id[v],val); int Query(int u,int v) int sum=0; while(top[u]!=top[v]) if(deep[top[u]]<deep[top[v]]) swap(u,v); // cout<<id[top[u]]<<" "<<id[u]<<endl; sum+=query(1,n,1,id[top[u]],id[u]); u=fa[top[u]]; if(deep[u]>deep[v]) swap(u,v); return sum+query(1,n,1,id[u],id[v]); void init() memset(head,-1,sizeof(head)); memset(lazy,-1,sizeof(lazy)); int main() int q; scanf("%d %d",&n,&q); init(); for(int i=1; i<n; i++) scanf("%d %d",&p[i].u,&p[i].v); add(p[i].u,p[i].v); add(p[i].v,p[i].u); dfs1(1,0,0); dfs2(1,1); // cout<<"?\n"; while(q--) int a,b,c,d; scanf("%d %d %d %d",&a,&b,&c,&d);// cout<<id[a]<<" "<<id[b]<<endl; Update(a,b,1); // cout<<"?\n"; printf("%d\n",Query(c,d)); Update(a,b,0); return 0;
以上是关于2018-2019 ACM-ICPC Brazil Subregional Programming Contest的主要内容,如果未能解决你的问题,请参考以下文章
2018-2019 ACM-ICPC Brazil Subregional Programming Contest PART (10/13)
2018-2019 ACM-ICPC Brazil Subregional Programming Contest
gym101908 [2018-2019 ACM-ICPC Brazil Subregional Programming Contest] 题解
2018-2019 ACM-ICPC Brazil Subregional Programming Contest B. Marbles
2019-2020 ACM-ICPC Brazil Subregional Programming Contest (7/10)
2019-2020 ACM-ICPC Brazil Subregional Programming Contest Problem A Artwork (并查集)