Codeforces Educational round 58

Ediv2 58

  • 随手AK.jpg

D

裸的虚树,在这里就不写了

E

傻逼贪心?这个题过的比$B$都多.jpg

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <bitset>
using namespace std;
#define N 500005
#define ll long long
int n,now_mx,maxx;char s[10];
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        int x,y;scanf("%s%d%d",s+1,&x,&y);
        if(x<y)swap(x,y);
        if(s[1]=='+')now_mx=max(x,now_mx),maxx=max(y,maxx);
        else puts(x>=now_mx&&y>=maxx?"YES":"NO");
    }
}

F

似乎正解的那个单调队列做法没啥意思啊...

直接暴力二分+剪枝就好了...

然后其实能卡掉,但是懒得去卡了.jpg

然后卡一卡常数就好了.jpg

随便剪一剪枝前测就能过.jpg

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <bitset>
using namespace std;
#define N 405
#define ll long long
int a[N],n,m,s,t,f,c,l,r;ll ans;
inline bool check(int x)
{
    register int i,tc=c;register int now=x;
    for(i=s;i<t;i++)
    {
        if(a[i+1]-a[i]>x)return 0;
        if(a[i+1]-a[i]>now)
        {
            if(!tc)return 0;
            tc--;now=x;
        }
        now-=a[i+1]-a[i];
    }return 1;
}
int main()
{
    scanf("%d%d",&n,&m);l=0,r=1<<30;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    while(m--)
    {
        scanf("%d%d%d%d",&s,&t,&f,&c);if(s>t)swap(s,t);
        if(check(ans/f))continue;
        l=(ans/f)+1;r=a[t]-a[s];
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(check(mid))r=mid;else l=mid+1;
        }ans=max((ll)l*f,ans);
    }
    printf("%lld\n",ans);
}

G

一个结论,能划分出的段数是线性基里的基的个数

证明嘛:

对于任意一个已经存在的基,都可以被一些数表达出来

然后就可以发现,不可能存在一个划分的段数比线性基里的基数更多(根据线性基的定义

然后就完了.jpg

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <bitset>
using namespace std;
#define N 200005
#define ll long long
int a[32],now;
void insert(int x)
{
    for(int i=30;~i;i--)if((x>>i)&1)
        if(a[i])x^=a[i];
        else {a[i]=x;return ;}
}
int main()
{
    int n,x;
    scanf("%d",&n);
    while(n--)scanf("%d",&x),insert(x),now^=x;
    if(!now)return puts("-1"),0;
    x=0;
    for(int i=30;~i;i--)if(a[i])x++;
    printf("%d\n",x);
}

猜你喜欢

转载自www.cnblogs.com/Winniechen/p/10352590.html