Codeforces Round #419

A

Karen and Morning

找最近的回文时间

模拟  往后推 判判就行

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
int tx,ty,T;
bool check(){
    int rx=tx/10,ry=tx%10;
    return ry*10+rx==ty;
}
int main(){
    scanf("%d:%d",&tx,&ty);
    while(1){
        if(check()){printf("%d\n",T);return 0;}
        T++,ty++;
        if(ty==60)tx++,ty=0;
        if(tx==24)tx=0;
    }
}

B

Karen and Coffee

差分前缀和推一发完事~

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=400050;
int n,k,q,xx,yy,a[N],s[N];
int main(){
    scanf("%d%d%d",&n,&k,&q);
    for(int i=1;i<=n;i++)scanf("%d%d",&xx,&yy),a[xx]++,a[yy+1]--;
    for(int i=1;i<N;i++)a[i]+=a[i-1];
    for(int i=1;i<N;i++)s[i]=s[i-1]+(a[i]>=k);
    for(int i=1;i<=q;i++)scanf("%d%d",&xx,&yy),printf("%d\n",s[yy]-s[xx-1]);
}

C

Karen and Game

贪心

先把整张图能删的都删了  再枚举行、列

输出比较烦

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=505;
int n,m,a[N][N],minn=N,rec[N],recl[N],T;
int main(){
    scanf("%d%d",&n,&m);memset(rec,0x3f,sizeof(rec));memset(recl,0x3f,sizeof(recl));
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&a[i][j]),minn=min(minn,a[i][j]);
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]-=minn;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)rec[i]=min(rec[i],a[i][j]);
        for(int j=1;j<=m;j++)a[i][j]-=rec[i];
    }
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(a[i][j]!=a[1][j]){puts("-1");return 0;}else recl[j]=min(recl[j],a[i][j]);
    for(int i=1;i<=n;i++)for(int j=1;j<=rec[i];j++)T++;
    for(int i=1;i<=m;i++)for(int j=1;j<=recl[i];j++)T++;
    if(n<m)for(int i=1;i<=minn;i++)for(int j=1;j<=n;j++)T++;
    else for(int i=1;i<=minn;i++)for(int j=1;j<=m;j++)T++;
    printf("%d\n",T);
    for(int i=1;i<=n;i++)for(int j=1;j<=rec[i];j++)printf("row %d\n",i);
    for(int i=1;i<=m;i++)for(int j=1;j<=recl[i];j++)printf("col %d\n",i);
    if(n<m)for(int i=1;i<=minn;i++)for(int j=1;j<=n;j++)printf("row %d\n",j);
    else for(int i=1;i<=minn;i++)for(int j=1;j<=m;j++)printf("col %d\n",j);
}

D

Karen and Test

这题好难啊...

把奇数列盖住

(观察?)可得

偶数列 一个数 等于它上一列左边的加上它上一列右边的

别问我怎么观察出来的  我没有观察出来

推到偶数列

杨辉三角

最后判一判剩的是加号还是减号

搞一起就行了..

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=200050,mod=1000000007;
int n,a[N],ans1,ans2,tot,fac[N],inv[N];
int C(int x,int y){return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;}
int pow(int x,int y){
    int r=1;
    while(y){
        if(y&1)r=1ll*r*x%mod;
        x=1ll*x*x%mod,y>>=1;
    }return r;
}
int main(){
    scanf("%d",&n),fac[0]=1;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),tot+=i-1;
    for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;
    for(int i=0;i<=n;i++)inv[i]=pow(fac[i],mod-2);
    if(n==1){printf("%d\n",a[1]);return 0;}
    if(n&1){
        for(int i=0;i<n;i++)a[i]=i&1?(a[i]+a[i+1]):(a[i]-a[i+1]);n--;
    }
    for(int i=1;i<=n;i+=2)ans1=(ans1+1ll*a[i]*C(n/2-1,i/2))%mod;
    for(int i=2;i<=n;i+=2)ans2=(ans2+1ll*a[i]*C(n/2-1,i/2-1))%mod;
    printf("%d\n",((tot&1?(ans1+ans2)%mod:ans1-ans2)+mod)%mod);
}

E

Karen and Supermarket

树形DP

f[x][j]  x子树必须用优惠券 选了j个

g[x][j] x子树必须不用优惠券 选了j个

g[x]->g[x]

f[x]&g[x]->f[x]

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=5050;
int first[N],nxt[N],v[N],tot,c[N],d[N],fa[N],n,k,f[N][N],g[N][N],size[N],ans;
void add(int x,int y){v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
void dfs(int x){
    f[x][0]=g[x][0]=0,size[x]=1;g[x][1]=c[x];
    for(int i=first[x];~i;i=nxt[i]){
        dfs(v[i]);
        for(int j=size[x];~j;j--){
            for(int k=size[v[i]];~k;k--){
                f[x][j+k]=min(f[x][j+k],f[x][j]+f[v[i]][k]);
            }
        }
        for(int j=size[x];~j;j--){
            for(int k=size[v[i]];~k;k--){
                g[x][j+k]=min(g[x][j+k],g[x][j]+g[v[i]][k]);
            }
        }
        size[x]+=size[v[i]];
    }
    for(int i=size[x];i;i--)f[x][i]=min(g[x][i],f[x][i-1]+c[x]-d[x]);
}
int main(){
    memset(first,-1,sizeof(first));
    memset(f,0x3f,sizeof(f));
    memset(g,0x3f,sizeof(g));
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&c[i],&d[i]);
        if(i!=1)scanf("%d",&fa[i]),add(fa[i],i);
    }dfs(1);
    for(int i=1;i<=n;i++)if(f[1][i]<=k)ans=i;
    printf("%d\n",ans);
}

Div1 D

Karen and Cards

线段树 区间覆盖 区间求和...

按照a排序 那么从大到小  nowb>b[i]||nowc>c[i]

用总方案数减去不合法的

就是all-左下角的一块矩形

a变小的时候  就会有nowb>b[i]&&nowc>c[i]

就把一块都覆盖住就好了

x轴是b y轴是c  单调递减

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=500050;
typedef long long ll;
int n,a,b,c,minn[N*8],maxx[N*8],lazy[N*8];
ll sum[N*8],ans;
struct Node{int x,y,z;}node[N];
void setlazy(int num,int pos,int wei){sum[pos]=1ll*num*wei;maxx[pos]=minn[pos]=lazy[pos]=wei;}
void push_down(int l,int r,int pos){
    int mid=(l+r)>>1,lson=pos<<1,rson=lson|1;
    setlazy(mid-l+1,lson,lazy[pos]),setlazy(r-mid,rson,lazy[pos]);
    lazy[pos]=0;
}
void push_up(int pos){
    int lson=pos<<1,rson=lson|1;
    sum[pos]=sum[lson]+sum[rson],minn[pos]=min(minn[lson],minn[rson]),maxx[pos]=max(maxx[lson],maxx[rson]);
}
void insert(int l,int r,int pos,int L,int R,int wei){
    if(wei<=minn[pos])return;
    if(lazy[pos])push_down(l,r,pos);
    if(l>=L&&r<=R&&maxx[pos]<=wei){setlazy(r-l+1,pos,wei);return;}
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(mid<L)insert(mid+1,r,rson,L,R,wei);
    else if(mid>=R)insert(l,mid,lson,L,R,wei);
    else insert(l,mid,lson,L,R,wei),insert(mid+1,r,rson,L,R,wei);
    push_up(pos);
}
bool cmp(Node a,Node b){return a.x>b.x;}
int main(){
    scanf("%d%d%d%d",&n,&a,&b,&c);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].z);
        insert(1,b,1,1,node[i].y,node[i].z);
    }sort(node+1,node+1+n,cmp);
    for(int i=a,j=1;i;i--){
        for(;j<=n&&node[j].x==i;j++)insert(1,b,1,1,node[j].y,c),insert(1,b,1,1,b,node[j].z);
        ans+=1ll*b*c-sum[1];
    }printf("%I64d\n",ans);
}

Div1 E  不会-> ->

时间: 2024-10-05 17:22:42

Codeforces Round #419的相关文章

Codeforces Round #419 (Div. 2) E. Karen and Supermarket(树形DP)

题目链接:Codeforces Round #419 (Div. 2) E. Karen and Supermarket 题意: 有n件物品,每个物品有一个价格,和一个使用优惠券的价格,不过这个优惠券有一个限制,必须要在第x个使用后才可以使用.现在有m的钱,问最多能买多少个物品. 题解: 每个优惠券都只与一个券有关,所以根据这个关系就可以构成一棵树. 考虑树形dp,dp[i][j][k(0|1)]表示第i个节点所构成的子树中买了j个物品,使用优惠券和不使用优惠券的最少钱. 转移方程看代码详细解释

Codeforces Round #419 C

C. Karen and Game 题意:给你一个矩阵,有2种操作,1是将某一行全部减1,2 是将某一列全部减1,问你最少多少次操作可以使得矩阵全部为0,并输出每次的操作,如果不可能,输出-1 思路:判断行和列的大小,如果行数大于列数,则优先进行操作1,否则优先进行操作2,将每次操作存入字符串,最后判断是否全部为0,xjb模拟就是了 AC代码: #include "iostream" #include "string.h" #include "stack&

Codeforces Round #419 (Div. 2) A-E

上紫啦! E题1:59压哨提交成功翻盘 (1:00就做完了调了一个小时,还好意思说出来? (逃)) 题面太长就不复制了,但是配图很可爱所以要贴过来 九条可怜酱好可爱呀 A - Karen and Morning 询问从当前时刻过多久,时间会形成回文串的形式. 暴力呀暴力 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<

Codeforces Round #419 B

B. Karen and Coffee 题意:输入第一行是n k q 分别表示有n个时间段 q个询问,每次询问给出l r 询问l r 时间内 有几个时间点在给出的时间段中出现不小于k次 思路:n个时间段用扫描线处理,询问就是问 l  r区间内有几个时间点在扫描线中的厚度不小于k,求2次前缀和就可以了 AC代码: #include "iostream" #include "string.h" #include "stack" #include &q

【贪心】 Codeforces Round #419 (Div. 1) A. Karen and Game

容易发现,删除的顺序不影响答案. 所以可以随便删. 如果行数大于列数,就先删列:否则先删行. #include<cstdio> #include<algorithm> using namespace std; int p1,ans1[510*110],ans2[510*110],p2; int n,m,a[110][110]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ f

Codeforces Round #419 (Div. 1) 补题 CF 815 A-E

A-C传送门 D Karen and Cards 技巧性很强的一道二分优化题 题意很简单 给定n个三元组,和三个维度的上限,问存在多少三元组,使得对于给定的n个三元组中的每一个,必有两个维度严格小于. 首先我们根据一个维度(c维)对n个三元组排序,然后枚举答案在这个维度的取值. 此时序列被分成了两个部分,前半部分 满足所有c大于等于i 后半部分满足所有c严格小于i(即已有一个维度小于) 通过累计,我们知道此时前半部a维的最大值ma和b维的最大值mb. 显然可能存在的三元组答案,必然首先满足a维和

Codeforces Round #419 (Div. 2)C. Karen and Game

C. Karen and Game 给定n行m列数字,每次可以让一行或一列都减一,求出让全部数字全为0的最小的次数,没有则输出-1: 比赛时没有考虑,n和m的大小问题,被hack了.5555555555555555555555555555 好的方法没有想到,只有一个死方法了. 1 #include <iostream> 2 #include <stdio.h> 3 #define long long ll 4 using namespace std; 5 int a[110][11

【找规律】【递推】【二项式定理】Codeforces Round #419 (Div. 1) B. Karen and Test

打个表出来看看,其实很明显. 推荐打这俩组 11 1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000000 12 1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000000 100000000000 打出表来看出来,n为偶数时,每隔两行,对原序列的奇数项分配的权重形成二项展开式. n为奇数时,每隔四行,形成二

Codeforces Round #419 (Div. 2)B. Karen and Coffee

B. Karen and Coffee 题意:给定n个区间,当一个数在k个区间以内则这个数可以被选中.有q个询问,问在某个区间能有多少个数可以被选中. 1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 const int MAX_N = 2e5+10; 5 int a[MAX_N], c[MAX_N], n, k, q; 6 int main(){ 7 int l, r; 8 scanf(&quo