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;
View Code

 

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;
View Code

 

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"); 
View Code

 

G. Gasoline (solve)

题意:

给你N个加油站 每个加油站需要ai的油 现在有M个油田可以提供油 接下来k条路用于油田到加油站的运输工作 且需要花费时间wi

每次运输量为无穷大且每个油田的车数量无穷大 让你求最少时间满足加油站的需求

思路:我们可以对于运输路径按wi排序 二分需要的路径数 也就是二分最大时间

每次check是否满流即可

技术图片View Code

 

 

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;
View Code

 

以上是关于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 (并查集)